updating to Eclipse 3.1 final version, tag v_574_R31X in the org.eclipse CVS tree.
diff --git a/org.eclipse.jdt.core/.project b/org.eclipse.jdt.core/.project
index 5e05291..7342551 100644
--- a/org.eclipse.jdt.core/.project
+++ b/org.eclipse.jdt.core/.project
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
- <name>org.eclipse.jdt.core</name>
+ <name>org.eclipse.jdt.core_shadows_HEAD</name>
<comment></comment>
<projects>
<project>org.eclipse.ant.core</project>
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..00dc181
--- /dev/null
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -0,0 +1,58 @@
+Manifest-Version: 1.0
+Main-Class: org.eclipse.jdt.internal.compiler.batch.Main
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true
+Bundle-Version: 3.1.1
+Bundle-ClassPath: .
+Bundle-Activator: org.eclipse.jdt.core.JavaCore
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Export-Package: org.eclipse.jdt.core,
+ org.eclipse.jdt.core.compiler,
+ org.eclipse.jdt.core.dom,
+ org.eclipse.jdt.core.dom.rewrite,
+ org.eclipse.jdt.core.eval,
+ org.eclipse.jdt.core.formatter,
+ org.eclipse.jdt.core.jdom,
+ org.eclipse.jdt.core.search,
+ org.eclipse.jdt.core.util,
+ org.eclipse.jdt.internal.codeassist;x-internal:=true,
+ org.eclipse.jdt.internal.codeassist.complete;x-internal:=true,
+ org.eclipse.jdt.internal.codeassist.impl;x-internal:=true,
+ org.eclipse.jdt.internal.codeassist.select;x-internal:=true,
+ org.eclipse.jdt.internal.compiler;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.ast;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.batch;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.classfmt;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.codegen;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.env;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.flow;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.impl;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.lookup;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.parser;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.parser.diagnose;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.problem;x-internal:=true,
+ org.eclipse.jdt.internal.compiler.util;x-internal:=true,
+ org.eclipse.jdt.internal.core;x-internal:=true,
+ org.eclipse.jdt.internal.core.builder;x-internal:=true,
+ org.eclipse.jdt.internal.core.dom.rewrite;x-internal:=true,
+ org.eclipse.jdt.internal.core.eval;x-internal:=true,
+ org.eclipse.jdt.internal.core.hierarchy;x-internal:=true,
+ org.eclipse.jdt.internal.core.index;x-internal:=true,
+ org.eclipse.jdt.internal.core.jdom;x-internal:=true,
+ org.eclipse.jdt.internal.core.search;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.indexing;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.matching;x-internal:=true,
+ org.eclipse.jdt.internal.core.search.processing;x-internal:=true,
+ org.eclipse.jdt.internal.core.util;x-internal:=true,
+ org.eclipse.jdt.internal.eval;x-internal:=true,
+ org.eclipse.jdt.internal.formatter;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.align;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.comment;x-internal:=true,
+ org.eclipse.jdt.internal.formatter.old;x-internal:=true
+Require-Bundle: org.eclipse.core.resources,
+ org.eclipse.core.runtime,
+ org.eclipse.text,
+ org.eclipse.team.core;resolution:=optional
+Eclipse-AutoStart: true
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
index 2edf25f..5542abe 100644
--- a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
@@ -62,7 +62,7 @@
Method compile = c.getMethod("compile", new Class[] {String[].class}); //$NON-NLS-1$
Object result = compile.invoke(batchCompilerInstance, new Object[] { cmd.getArguments()});
final boolean resultValue = ((Boolean) result).booleanValue();
- if (!resultValue && this.verbose) {
+ if (!resultValue && this.logFileName != null) {
System.out.println(AntAdapterMessages.getString("ant.jdtadapter.error.compilationFailed", this.logFileName)); //$NON-NLS-1$
}
return resultValue;
@@ -294,14 +294,19 @@
/*
* verbose option
*/
- if (this.verbose) {
- cmd.createArgument().setValue("-verbose"); //$NON-NLS-1$
+ if (this.verbose && this.destDir != null) {
+ /*
+ * if destDir is null, we don't generate any log.
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=97744
+ */
+ // Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=96605
+ // cmd.createArgument().setValue("-verbose"); //$NON-NLS-1$
/*
* extra option allowed by the Eclipse compiler
*/
cmd.createArgument().setValue("-log"); //$NON-NLS-1$
this.logFileName = this.destDir.getAbsolutePath() + ".log"; //$NON-NLS-1$
- cmd.createArgument().setValue(this.logFileName);
+ cmd.createArgument().setValue(this.logFileName);
}
/*
@@ -366,7 +371,7 @@
* srcdir option.
*/
logAndAddFilesToCompile(cmd);
- return cmd;
+ return cmd;
}
/**
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
index 59a97fd..9ac9be7 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
@@ -11,13 +11,14 @@
package org.eclipse.jdt.internal.compiler.batch;
import java.io.File;
+import java.io.IOException;
import java.util.Hashtable;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
-import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
-public class ClasspathDirectory implements FileSystem.Classpath, SuffixConstants {
+public class ClasspathDirectory extends ClasspathLocation {
String path;
Hashtable directoryCache;
@@ -28,8 +29,14 @@
public static final int SOURCE = 1;
public static final int BINARY = 2;
-ClasspathDirectory(File directory, String encoding, int mode) {
- this.mode = mode;
+ClasspathDirectory(File directory, String encoding, int mode, AccessRuleSet accessRuleSet) {
+ super(accessRuleSet);
+ if (mode == 0){
+ this.mode = SOURCE | BINARY;
+ }
+ else {
+ this.mode = mode;
+ }
this.path = directory.getAbsolutePath();
if (!this.path.endsWith(File.separator))
this.path += File.separator;
@@ -38,9 +45,8 @@
}
ClasspathDirectory(File directory, String encoding) {
- this(directory, encoding, SOURCE | BINARY); // by default consider both sources and binaries
+ this(directory, encoding, SOURCE | BINARY, null); // by default consider both sources and binaries
}
-
String[] directoryList(String qualifiedPackageName) {
String[] dirList = (String[]) this.directoryCache.get(qualifiedPackageName);
if (dirList == this.missingPackageHolder) return null; // package exists in another classpath directory or jar
@@ -90,24 +96,34 @@
if (sourceExists) {
String fullSourcePath = this.path + qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - 6) + SUFFIX_STRING_java;
if (!binaryExists)
- return new NameEnvironmentAnswer(new CompilationUnit(null, fullSourcePath, this.encoding), null/* TODO no access restriction*/);
-
+ return new NameEnvironmentAnswer(new CompilationUnit(null,
+ fullSourcePath, this.encoding),
+ fetchAccessRestriction(qualifiedBinaryFileName));
String fullBinaryPath = this.path + qualifiedBinaryFileName;
long binaryModified = new File(fullBinaryPath).lastModified();
long sourceModified = new File(fullSourcePath).lastModified();
if (sourceModified > binaryModified)
- return new NameEnvironmentAnswer(new CompilationUnit(null, fullSourcePath, this.encoding), null/* TODO no access restriction*/);
+ return new NameEnvironmentAnswer(new CompilationUnit(null,
+ fullSourcePath, this.encoding),
+ fetchAccessRestriction(qualifiedBinaryFileName));
}
if (binaryExists) {
try {
- ClassFileReader reader = ClassFileReader.read(this.path + qualifiedBinaryFileName);
- if (reader != null) return new NameEnvironmentAnswer(reader, null/* TODO no access restriction*/);
- } catch (Exception e) {
+ ClassFileReader reader = ClassFileReader.read(this.path
+ + qualifiedBinaryFileName);
+ if (reader != null)
+ return new NameEnvironmentAnswer(
+ reader,
+ fetchAccessRestriction(qualifiedBinaryFileName));
+ } catch (Exception e) {
// treat as if file is missing
}
}
return null;
}
+public void initialize() throws IOException {
+ // nothing to do
+}
public boolean isPackage(String qualifiedPackageName) {
return directoryList(qualifiedPackageName) != null;
}
@@ -117,4 +133,10 @@
public String toString() {
return "ClasspathDirectory " + this.path; //$NON-NLS-1$
}
+public String normalizedPath() {
+ return this.path;
+}
+public String getPath() {
+ return this.path;
+}
}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
index 56b037a..5697cee 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
@@ -18,34 +18,41 @@
import java.util.zip.ZipFile;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
-public class ClasspathJar implements FileSystem.Classpath {
+public class ClasspathJar extends ClasspathLocation {
-ZipFile zipFile;
-Hashtable packageCache;
-boolean closeZipFileAtEnd;
+private File file;
+private ZipFile zipFile;
+private boolean closeZipFileAtEnd;
+private Hashtable packageCache;
public ClasspathJar(File file) throws IOException {
- this(new ZipFile(file), true);
+ this(file, true, null);
}
-public ClasspathJar(ZipFile zipFile, boolean closeZipFileAtEnd) {
- this.zipFile = zipFile;
- this.packageCache = null;
+public ClasspathJar(File file, boolean closeZipFileAtEnd, AccessRuleSet accessRuleSet) {
+ super(accessRuleSet);
+ this.file = file;
this.closeZipFileAtEnd = closeZipFileAtEnd;
-}
+}
+
public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
if (!isPackage(qualifiedPackageName))
return null; // most common case
try {
ClassFileReader reader = ClassFileReader.read(this.zipFile, qualifiedBinaryFileName);
- if (reader != null) return new NameEnvironmentAnswer(reader, null /*no access restriction*/);
+ if (reader != null) return new NameEnvironmentAnswer(reader,
+ fetchAccessRestriction(qualifiedBinaryFileName));
} catch (Exception e) {
// treat as if class file is missing
}
return null;
}
+public void initialize() throws IOException {
+ this.zipFile = new ZipFile(this.file);
+}
public boolean isPackage(String qualifiedPackageName) {
if (this.packageCache != null)
return this.packageCache.containsKey(qualifiedPackageName);
@@ -72,14 +79,22 @@
public void reset() {
if (this.zipFile != null && this.closeZipFileAtEnd) {
try {
- this.zipFile.close();
+ this.zipFile.close();
} catch(IOException e) {
// ignore
}
+ this.zipFile = null;
}
this.packageCache = null;
}
public String toString() {
- return "Classpath for jar file " + this.zipFile.getName(); //$NON-NLS-1$
+ return "Classpath for jar file " + this.file.getPath(); //$NON-NLS-1$
+}
+public String normalizedPath(){
+ String rawName = this.file.getPath();
+ return rawName.substring(0, rawName.lastIndexOf('.'));
+}
+public String getPath(){
+ return this.file.getPath();
}
}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.java
new file mode 100644
index 0000000..a0219b7
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+
+public abstract class ClasspathLocation implements FileSystem.Classpath,
+ SuffixConstants {
+
+ private AccessRuleSet accessRuleSet;
+
+ public ClasspathLocation(AccessRuleSet accessRuleSet) {
+ this.accessRuleSet = accessRuleSet;
+ }
+
+ /**
+ * Return the first access rule which is violated when accessing a given
+ * type, or null if no 'non accessible' access rule applies.
+ *
+ * @param qualifiedBinaryFileName
+ * tested type specification, formed as:
+ * "org/eclipse/jdt/core/JavaCore.class"
+ * @return the first access rule which is violated when accessing a given
+ * type, or null if none applies
+ */
+ AccessRestriction fetchAccessRestriction(String qualifiedBinaryFileName) {
+ if (this.accessRuleSet == null)
+ return null;
+ return this.accessRuleSet
+ .getViolatedRestriction(
+ qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - SUFFIX_CLASS.length)
+ .toCharArray());
+ }
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
index a98b0e7..81cef77 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
@@ -12,9 +12,9 @@
import java.io.File;
import java.io.IOException;
-import java.util.zip.ZipFile;
import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
@@ -31,6 +31,24 @@
* a new name environment without creating a new object.
*/
void reset();
+ /**
+ * Return a normalized path for file based classpath entries. This is an absolute path
+ * ending with a file separator for directories, an absolute path deprived from the '.jar'
+ * (resp. '.zip') extension for jar (resp. zip) files.
+ * @return a normalized path for file based classpath entries
+ */
+ String normalizedPath();
+ /**
+ * Return the path for file based classpath entries. This is an absolute path
+ * ending with a file separator for directories, an absolute path including from the '.jar'
+ * (resp. '.zip') extension for jar (resp. zip) files.
+ * @return the path for file based classpath entries
+ */
+ String getPath();
+ /**
+ * Initialize the entry
+ */
+ void initialize() throws IOException;
}
/*
classPathNames is a collection is Strings representing the full path of each class path
@@ -41,49 +59,64 @@
this(classpathNames, initialFileNames, encoding, null);
}
public FileSystem(String[] classpathNames, String[] initialFileNames, String encoding, int[] classpathDirectoryModes) {
- int classpathSize = classpathNames.length;
+ final int classpathSize = classpathNames.length;
this.classpaths = new Classpath[classpathSize];
- String[] pathNames = new String[classpathSize];
- int problemsOccured = 0;
+ int counter = 0;
for (int i = 0; i < classpathSize; i++) {
+ Classpath classpath = getClasspath(classpathNames[i], encoding,
+ classpathDirectoryModes == null ? 0
+ : classpathDirectoryModes[i], null);
try {
- File file = new File(convertPathSeparators(classpathNames[i]));
- if (file.isDirectory()) {
- if (file.exists()) {
- if (classpathDirectoryModes == null){
- this.classpaths[i] = new ClasspathDirectory(file, encoding);
- } else {
- this.classpaths[i] = new ClasspathDirectory(file, encoding, classpathDirectoryModes[i]);
- }
- pathNames[i] = ((ClasspathDirectory) this.classpaths[i]).path;
- }
- } else {
- String lowercaseClasspathName = classpathNames[i].toLowerCase();
- if (lowercaseClasspathName.endsWith(SUFFIX_STRING_jar)
- || lowercaseClasspathName.endsWith(SUFFIX_STRING_zip)) {
- this.classpaths[i] = this.getClasspathJar(file); // will throw an IOException if file does not exist
- pathNames[i] = classpathNames[i].substring(0, classpathNames[i].lastIndexOf('.'));
- }
- }
+ classpath.initialize();
+ this.classpaths[counter++] = classpath;
} catch (IOException e) {
- this.classpaths[i] = null;
+ // ignore
}
- if (this.classpaths[i] == null)
- problemsOccured++;
}
- if (problemsOccured > 0) {
- Classpath[] newPaths = new Classpath[classpathSize - problemsOccured];
- String[] newNames = new String[classpathSize - problemsOccured];
- for (int i = 0, current = 0; i < classpathSize; i++)
- if (this.classpaths[i] != null) {
- newPaths[current] = this.classpaths[i];
- newNames[current++] = pathNames[i];
- }
- classpathSize = newPaths.length;
- this.classpaths = newPaths;
- pathNames = newNames;
+ if (counter != classpathSize) {
+ System.arraycopy(this.classpaths, 0, (this.classpaths = new Classpath[counter]), 0, counter);
}
-
+ initializeKnownFileNames(initialFileNames);
+}
+FileSystem(Classpath[] paths, String[] initialFileNames) {
+ final int length = paths.length;
+ int counter = 0;
+ this.classpaths = new FileSystem.Classpath[length];
+ for (int i = 0; i < length; i++) {
+ final Classpath classpath = paths[i];
+ try {
+ classpath.initialize();
+ this.classpaths[counter++] = classpath;
+ } catch(IOException exception) {
+ // ignore
+ }
+ }
+ if (counter != length) {
+ // should not happen
+ System.arraycopy(this.classpaths, 0, (this.classpaths = new FileSystem.Classpath[counter]), 0, counter);
+ }
+ initializeKnownFileNames(initialFileNames);
+}
+static Classpath getClasspath(String classpathName, String encoding,
+ int classpathDirectoryMode, AccessRuleSet accessRuleSet) {
+ Classpath result = null;
+ File file = new File(convertPathSeparators(classpathName));
+ if (file.isDirectory()) {
+ if (file.exists()) {
+ result = new ClasspathDirectory(file, encoding,
+ classpathDirectoryMode, accessRuleSet);
+ }
+ } else {
+ String lowercaseClasspathName = classpathName.toLowerCase();
+ if (lowercaseClasspathName.endsWith(SUFFIX_STRING_jar)
+ || lowercaseClasspathName.endsWith(SUFFIX_STRING_zip)) {
+ result = new ClasspathJar(file, true, accessRuleSet);
+ // will throw an IOException if file does not exist
+ }
+ }
+ return result;
+}
+private void initializeKnownFileNames(String[] initialFileNames) {
this.knownFileNames = new String[initialFileNames.length];
for (int i = initialFileNames.length; --i >= 0;) {
String fileName = initialFileNames[i];
@@ -92,20 +125,26 @@
fileName = fileName.substring(0, fileName.lastIndexOf('.')); // remove trailing ".java"
fileName = convertPathSeparators(fileName);
- for (int j = 0; j < classpathSize; j++)
- if (fileName.startsWith(pathNames[j]))
- matchingPathName = pathNames[j];
+ for (int j = 0; j < classpaths.length; j++){
+ String matchCandidate = this.classpaths[j].normalizedPath();
+ if (this.classpaths[j] instanceof ClasspathDirectory &&
+ fileName.startsWith(matchCandidate) &&
+ (matchingPathName == null ||
+ matchCandidate.length() < matchingPathName.length()))
+ matchingPathName = matchCandidate;
+ }
if (matchingPathName == null)
this.knownFileNames[i] = fileName; // leave as is...
else
this.knownFileNames[i] = fileName.substring(matchingPathName.length());
+ matchingPathName = null;
}
}
public void cleanup() {
for (int i = 0, max = this.classpaths.length; i < max; i++)
this.classpaths[i].reset();
}
-private String convertPathSeparators(String path) {
+private static String convertPathSeparators(String path) {
return File.separatorChar == '/'
? path.replace('\\', '/')
: path.replace('/', '\\');
@@ -153,7 +192,7 @@
return null;
}
public ClasspathJar getClasspathJar(File file) throws IOException {
- return new ClasspathJar(new ZipFile(file), true);
+ return new ClasspathJar(file, true, null);
}
public boolean isPackage(char[][] compoundName, char[] packageName) {
String qualifiedPackageName = new String(CharOperation.concatWith(compoundName, packageName, '/'));
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index 19ed7a8..87588d8 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -23,8 +23,11 @@
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
@@ -45,6 +48,8 @@
import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
import org.eclipse.jdt.internal.compiler.IProblemFactory;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
@@ -311,7 +316,7 @@
String.valueOf(time),
String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0) }));
}
- public void logClasspath(String[] classpaths) {
+ public void logClasspath(FileSystem.Classpath[] classpaths) {
if (classpaths == null) return;
if (this.isXml) {
final int length = classpaths.length;
@@ -320,7 +325,7 @@
this.printTag(CLASSPATHS, null, true, false);
for (int i = 0; i < length; i++) {
this.parameters.clear();
- String classpath = classpaths[i];
+ String classpath = classpaths[i].getPath();
parameters.put(PATH, classpath);
File f = new File(classpath);
String id = null;
@@ -379,7 +384,7 @@
} catch (IOException e) {
this.logNoClassFileCreated(fileName);
}
- }
+ }
}
public void logCommandLineArguments(String[] commandLineArguments) {
@@ -726,7 +731,7 @@
Main.bind("compiler.version"), //$NON-NLS-1$
Main.bind("compiler.copyright") //$NON-NLS-1$
}
- )); //$NON-NLS-1$
+ ));
}
/**
@@ -816,6 +821,11 @@
private void printlnOut(String s) {
this.out.println(s);
+ if (!this.isXml) {
+ if (this.log != null) {
+ this.log.println(s);
+ }
+ }
}
/**
@@ -857,13 +867,17 @@
}
public void setLog(String logFileName) throws InvalidInputException {
+ final Date date = new Date();
+ final SimpleDateFormat dateFormat = new SimpleDateFormat("d MMM yyyy HH:mm:ss", Locale.getDefault());//$NON-NLS-1$
try {
this.log = new PrintWriter(new FileOutputStream(logFileName, false));
int index = logFileName.lastIndexOf('.');
- if (index != 0) {
+ if (index != -1) {
if (logFileName.substring(index).toLowerCase().equals(".xml")) { //$NON-NLS-1$
this.isXml = true;
this.log.println(XML_HEADER);
+ // insert time stamp as comment
+ this.log.println("<!-- " + dateFormat.format(date) + " -->");//$NON-NLS-1$//$NON-NLS-2$
this.log.println(XML_DTD_DECLARATION);
this.tab = 0;
parameters.clear();
@@ -871,7 +885,11 @@
parameters.put(COMPILER_VERSION, Main.bind("compiler.version")); //$NON-NLS-1$//$NON-NLS-2$
parameters.put(COMPILER_COPYRIGHT, Main.bind("compiler.copyright")); //$NON-NLS-1$//$NON-NLS-2$
this.printTag(COMPILER, parameters, true, false);
+ } else {
+ this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$//$NON-NLS-2$
}
+ } else {
+ this.log.println("# " + dateFormat.format(date));//$NON-NLS-1$//$NON-NLS-2$
}
} catch (FileNotFoundException e) {
throw new InvalidInputException(Main.bind("configure.cannotOpenLog")); //$NON-NLS-1$
@@ -925,7 +943,7 @@
public final static String bundleName =
"org.eclipse.jdt.internal.compiler.batch.messages"; //$NON-NLS-1$
- public String[] classpaths;
+ FileSystem.Classpath[] checkedClasspaths;
public String destinationPath;
public String[] encodings;
public Logger logger;
@@ -1184,11 +1202,18 @@
final int InsideDefaultEncoding = 64;
final int InsideBootClasspath = 128;
final int InsideMaxProblems = 256;
+ final int InsideExtdirs = 512;
+ final int InsideSourcepath = 1024;
+
final int Default = 0;
- String[] bootclasspaths = null;
int DEFAULT_SIZE_CLASSPATH = 4;
- int pathCount = 0;
- int bootclasspathCount = 0;
+ ArrayList bootclasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH),
+ extdirsClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH),
+ extdirsNames = new ArrayList(DEFAULT_SIZE_CLASSPATH),
+ sourcepathClasspaths = new ArrayList(DEFAULT_SIZE_CLASSPATH),
+ classpaths = new ArrayList(DEFAULT_SIZE_CLASSPATH);
+ String currentClasspathName = null;
+ ArrayList currentRuleSpecs = new ArrayList(DEFAULT_SIZE_CLASSPATH);
int index = -1, filesCount = 0, argCount = argv.length;
int mode = Default;
this.repetitions = 0;
@@ -1264,7 +1289,8 @@
currentArg = newCommandLineArgs[index];
customEncoding = null;
- if (currentArg.endsWith("]")) { //$NON-NLS-1$
+ if (currentArg.endsWith("]") && !(mode == InsideBootClasspath || mode == InsideClasspath || //$NON-NLS-1$
+ mode == InsideSourcepath) ) {
// look for encoding specification
int encodingStart = currentArg.indexOf('[') + 1;
int encodingEnd = currentArg.length() - 1;
@@ -1376,20 +1402,30 @@
}
if (currentArg.equals("-classpath") //$NON-NLS-1$
|| currentArg.equals("-cp")) { //$NON-NLS-1$ //$NON-NLS-2$
- if (pathCount == 0) {
- this.classpaths = new String[DEFAULT_SIZE_CLASSPATH];
- }
mode = InsideClasspath;
continue;
}
if (currentArg.equals("-bootclasspath")) {//$NON-NLS-1$
- if (bootclasspathCount > 0)
+ if (bootclasspaths.size() > 0)
throw new InvalidInputException(
Main.bind("configure.duplicateBootClasspath", currentArg)); //$NON-NLS-1$
- bootclasspaths = new String[DEFAULT_SIZE_CLASSPATH];
mode = InsideBootClasspath;
continue;
}
+ if (currentArg.equals("-sourcepath")) {//$NON-NLS-1$
+ if (sourcepathClasspaths.size() > 0)
+ throw new InvalidInputException(
+ Main.bind("configure.duplicateSourcepath", currentArg)); //$NON-NLS-1$
+ mode = InsideSourcepath;
+ continue;
+ }
+ if (currentArg.equals("-extdirs")) {//$NON-NLS-1$
+ if (extdirsNames.size() > 0)
+ throw new InvalidInputException(
+ Main.bind("configure.duplicateExtdirs", currentArg)); //$NON-NLS-1$
+ mode = InsideExtdirs;
+ continue;
+ }
if (currentArg.equals("-progress")) { //$NON-NLS-1$
mode = Default;
this.showProgress = true;
@@ -1608,7 +1644,8 @@
this.options.put(
CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment,
isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
- } else if (token.equals("syntheticAccess")) { //$NON-NLS-1$
+ } else if (token.equals("syntheticAccess") //$NON-NLS-1$
+ || token.equals("synthetic-access")) { //$NON-NLS-1$
this.options.put(
CompilerOptions.OPTION_ReportSyntheticAccessEmulation,
isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
@@ -1660,6 +1697,14 @@
this.options.put(
CompilerOptions.OPTION_ReportFinalParameterBound,
isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ } else if (token.equals("suppress")) {//$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_SuppressWarnings,
+ isEnabling ? CompilerOptions.ENABLED : CompilerOptions.DISABLED);
+ } else if (token.equals("warningToken")) {//$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_ReportUnhandledWarningToken,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
} else if (token.equals("unnecessaryElse")) {//$NON-NLS-1$
this.options.put(
CompilerOptions.OPTION_ReportUnnecessaryElse,
@@ -1751,7 +1796,8 @@
this.options.put(
CompilerOptions.OPTION_ReportUnusedDeclaredThrownException,
isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
- } else if (token.equals("unqualifiedField")) { //$NON-NLS-1$
+ } else if (token.equals("unqualifiedField") //$NON-NLS-1$
+ || token.equals("unqualified-field-access")) { //$NON-NLS-1$
this.options.put(
CompilerOptions.OPTION_ReportUnqualifiedFieldAccess,
isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
@@ -1771,11 +1817,11 @@
this.options.put(
CompilerOptions.OPTION_ReportAutoboxing,
isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
- } else if (token.equals("Override")) { //$NON-NLS-1$
+ } else if (token.equals("over-ann")) { //$NON-NLS-1$
this.options.put(
CompilerOptions.OPTION_ReportMissingOverrideAnnotation,
isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
- } else if (token.equals("Deprecated")) { //$NON-NLS-1$
+ } else if (token.equals("dep-ann")) { //$NON-NLS-1$
this.options.put(
CompilerOptions.OPTION_ReportMissingDeprecatedAnnotation,
isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
@@ -1783,10 +1829,47 @@
this.options.put(
CompilerOptions.OPTION_ReportAnnotationSuperInterface,
isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
- } else if (token.equals("enumSwitch")) { //$NON-NLS-1$
+ } else if (token.equals("enumSwitch") //$NON-NLS-1$
+ || token.equals("incomplete-switch")) { //$NON-NLS-1$
this.options.put(
CompilerOptions.OPTION_ReportIncompleteEnumSwitch,
isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ } else if (token.equals("hiding")) { //$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_ReportHiddenCatchBlock,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ this.options.put(
+ CompilerOptions.OPTION_ReportLocalVariableHiding,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ this.options.put(
+ CompilerOptions.OPTION_ReportFieldHiding,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ this.options.put(
+ CompilerOptions.OPTION_ReportTypeParameterHiding,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ } else if (token.equals("static-access")) { //$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_ReportNonStaticAccessToStatic,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ this.options.put(
+ CompilerOptions.OPTION_ReportIndirectStaticAccess,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ } else if (token.equals("unused")) { //$NON-NLS-1$
+ this.options.put(
+ CompilerOptions.OPTION_ReportUnusedLocal,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ this.options.put(
+ CompilerOptions.OPTION_ReportUnusedParameter,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ this.options.put(
+ CompilerOptions.OPTION_ReportUnusedImport,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ this.options.put(
+ CompilerOptions.OPTION_ReportUnusedPrivateMember,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+ this.options.put(
+ CompilerOptions.OPTION_ReportUnusedDeclaredThrownException,
+ isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
} else {
throw new InvalidInputException(Main.bind("configure.invalidWarning", token)); //$NON-NLS-1$
}
@@ -1814,6 +1897,35 @@
useEnableJavadoc = true;
continue;
}
+ // tolerated javac options - quietly filtered out
+ if (currentArg.startsWith("-X")) { //$NON-NLS-1$
+ mode = Default;
+ continue;
+ }
+ if (currentArg.startsWith("-J")) { //$NON-NLS-1$
+ mode = Default;
+ continue;
+ }
+ if (currentArg.equals("-O")) { //$NON-NLS-1$
+ mode = Default;
+ continue;
+ }
+
+ if (currentArg.equals("-sourcepath")) {//$NON-NLS-1$
+ if (sourcepathClasspaths.size() > 0)
+ throw new InvalidInputException(
+ Main.bind("configure.duplicateSourcepath", currentArg)); //$NON-NLS-1$
+ mode = InsideSourcepath;
+ continue;
+ }
+ if (currentArg.equals("-extdirs")) {//$NON-NLS-1$
+ if (extdirsNames.size() > 0)
+ throw new InvalidInputException(
+ Main.bind("configure.duplicateExtdirs", currentArg)); //$NON-NLS-1$
+ mode = InsideExtdirs;
+ continue;
+ }
+
if (mode == TargetSetting) {
if (didSpecifyTarget) {
throw new InvalidInputException(
@@ -1913,40 +2025,100 @@
mode = Default;
continue;
}
- if (mode == InsideClasspath) {
- StringTokenizer tokenizer = new StringTokenizer(currentArg, File.pathSeparator);
+ if (mode == InsideClasspath || mode == InsideBootClasspath || mode == InsideSourcepath) {
+ StringTokenizer tokenizer = new StringTokenizer(currentArg,
+ File.pathSeparator + "[]", true); //$NON-NLS-1$
+ // state machine
+ final int start = 0;
+ final int readyToClose = 1;
+ // 'path' 'path1[rule];path2'
+ final int readyToCloseEndingWithRules = 2;
+ // 'path[rule]' 'path1;path2[rule]'
+ final int readyToCloseOrOtherEntry = 3;
+ // 'path[rule];' 'path;' 'path1;path2;'
+ final int rulesNeedAnotherRule = 4;
+ // 'path[rule1;'
+ final int rulesStart = 5;
+ // 'path[' 'path1;path2['
+ final int rulesReadyToClose = 6;
+ // 'path[rule' 'path[rule1;rule2'
+ final int error = 99;
+ int state = start;
+ String token = null;
while (tokenizer.hasMoreTokens()) {
- int length;
- if ((length = this.classpaths.length) <= pathCount) {
- System.arraycopy(
- this.classpaths,
- 0,
- (this.classpaths = new String[length * 2]),
- 0,
- length);
+ token = tokenizer.nextToken();
+ if (token.equals(File.pathSeparator)) {
+ switch (state) {
+ case readyToClose:
+ case readyToCloseEndingWithRules:
+ case readyToCloseOrOtherEntry:
+ state = readyToCloseOrOtherEntry;
+ addNewEntry(InsideClasspath, InsideSourcepath, bootclasspaths, classpaths, sourcepathClasspaths, currentClasspathName, currentRuleSpecs, mode, customEncoding);
+ break;
+ case rulesReadyToClose:
+ state = rulesNeedAnotherRule;
+ break;
+ default:
+ state = error;
+ }
+ } else if (token.equals("[")) { //$NON-NLS-1$
+ switch (state) {
+ case readyToClose:
+ state = rulesStart;
+ break;
+ default:
+ state = error;
+ }
+ } else if (token.equals("]")) { //$NON-NLS-1$
+ switch (state) {
+ case rulesReadyToClose:
+ state = readyToCloseEndingWithRules;
+ break;
+ default:
+ state = error;
+ }
+
+ } else {
+ // regular word
+ switch (state) {
+ case start:
+ case readyToCloseOrOtherEntry:
+ state = readyToClose;
+ currentClasspathName = token;
+ break;
+ case rulesNeedAnotherRule:
+ case rulesStart:
+ state = rulesReadyToClose;
+ currentRuleSpecs.add(token);
+ break;
+ default:
+ state = error;
+ }
}
- this.classpaths[pathCount++] = tokenizer.nextToken();
+ }
+ switch(state) {
+ case readyToClose :
+ case readyToCloseEndingWithRules :
+ case readyToCloseOrOtherEntry :
+ addNewEntry(InsideClasspath, InsideSourcepath, bootclasspaths, classpaths, sourcepathClasspaths, currentClasspathName, currentRuleSpecs, mode, customEncoding);
+ break;
+ default :
+ // we go on anyway
+ this.logger.logIncorrectClasspath(currentArg);
}
mode = Default;
continue;
}
- if (mode == InsideBootClasspath) {
- StringTokenizer tokenizer = new StringTokenizer(currentArg, File.pathSeparator);
- while (tokenizer.hasMoreTokens()) {
- int length;
- if ((length = bootclasspaths.length) <= bootclasspathCount) {
- System.arraycopy(
- bootclasspaths,
- 0,
- (bootclasspaths = new String[length * 2]),
- 0,
- length);
- }
- bootclasspaths[bootclasspathCount++] = tokenizer.nextToken();
- }
+ if (mode == InsideExtdirs) {
+ StringTokenizer tokenizer = new StringTokenizer(currentArg, File.pathSeparator, false);
+ while (tokenizer.hasMoreTokens())
+ extdirsNames.add(tokenizer.nextToken());
+ if (extdirsNames.size() == 0) // empty entry
+ extdirsNames.add(""); //$NON-NLS-1$
mode = Default;
continue;
- }
+ }
+
//default is input directory
currentArg = currentArg.replace('/', File.separatorChar);
if (currentArg.endsWith(File.separator))
@@ -1996,6 +2168,14 @@
mode = Default;
continue;
}
+
+
+ if (this.log != null) {
+ this.logger.setLog(this.log);
+ } else {
+ this.showProgress = false;
+ }
+
if (printUsageRequired || filesCount == 0) {
printUsage();
this.proceed = false;
@@ -2012,22 +2192,30 @@
(this.filenames = new String[filesCount]),
0,
filesCount);
- if (pathCount == 0) {
+ if (classpaths.size() == 0) {
// no user classpath specified.
String classProp = System.getProperty("java.class.path"); //$NON-NLS-1$
if ((classProp == null) || (classProp.length() == 0)) {
this.logger.logNoClasspath(); //$NON-NLS-1$
- classProp = System.getProperty("user.dir"); //$NON-NLS-1$
}
- StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator);
- this.classpaths = new String[tokenizer.countTokens() + 1];
- while (tokenizer.hasMoreTokens()) {
- this.classpaths[pathCount++] = tokenizer.nextToken();
+ else {
+ StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator);
+ String token;
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ FileSystem.Classpath currentClasspath = FileSystem
+ .getClasspath(token, customEncoding, 0, null);
+ if (currentClasspath != null) {
+ classpaths.add(currentClasspath);
+ } else {
+ this.logger.logIncorrectClasspath(token);
+ // should not happen - we go on anyway
+ }
+ }
}
- this.classpaths[pathCount++] = System.getProperty("user.dir");//$NON-NLS-1$
}
- if (bootclasspathCount == 0) {
+ if (bootclasspaths.size() == 0) {
/* no bootclasspath specified
* we can try to retrieve the default librairies of the VM used to run
* the batch compiler
@@ -2042,74 +2230,89 @@
/*
* Handle >= JDK 1.2.2 settings: retrieve rt.jar
*/
- String javaHome = System.getProperty("java.home");//$NON-NLS-1$
- if (javaHome != null) {
- File javaHomeFile = new File(javaHome);
- if (javaHomeFile.exists()) {
- try {
- javaHomeFile = new File(javaHomeFile.getCanonicalPath());
- // add all jars in the lib subdirectory
- File[] directoriesToCheck = new File[] { new File(javaHomeFile, "lib"), new File(javaHomeFile, "lib/ext")};//$NON-NLS-1$//$NON-NLS-2$
- File[][] systemLibrariesJars = getLibrariesFiles(directoriesToCheck);
- if (systemLibrariesJars != null) {
- int length = getLength(systemLibrariesJars);
- bootclasspaths = new String[length];
- for (int i = 0, max = systemLibrariesJars.length; i < max; i++) {
- File[] current = systemLibrariesJars[i];
- if (current != null) {
- for (int j = 0, max2 = current.length; j < max2; j++) {
- bootclasspaths[bootclasspathCount++] = current[j].getAbsolutePath();
- }
+ if (getJavaHome() != null) {
+ File[] directoriesToCheck = new File[] {
+ new File(getJavaHome(), "lib") //$NON-NLS-1$
+ };
+ File[][] systemLibrariesJars = getLibrariesFiles(directoriesToCheck);
+ if (systemLibrariesJars != null) {
+ for (int i = 0, max = systemLibrariesJars.length; i < max; i++) {
+ File[] current = systemLibrariesJars[i];
+ if (current != null) {
+ for (int j = 0, max2 = current.length; j < max2; j++) {
+ FileSystem.Classpath classpath =
+ FileSystem.getClasspath(
+ current[j].getAbsolutePath(),
+ null, 0, null);
+ if (classpath != null) {
+ bootclasspaths.add(classpath);
}
}
}
- } catch (IOException e) {
- // cannot retrieve libraries
}
- }
- }
- }
-
- if (this.log != null) {
- this.logger.setLog(this.log);
- } else {
- this.showProgress = false;
- }
-
- if (this.classpaths == null) {
- this.classpaths = new String[0];
- }
- /*
- * We put the bootclasspath at the beginning of the classpath entries
+ }
+ }
+ }
+
+ /*
+ * Feed extdirsNames according to:
+ * - -extdirs first if present;
+ * - else java.ext.dirs if defined;
+ * - else default extensions directory for the platform.
*/
- String[] newclasspaths = null;
- if ((pathCount + bootclasspathCount) != this.classpaths.length) {
- newclasspaths = new String[pathCount + bootclasspathCount];
- } else {
- newclasspaths = this.classpaths;
- }
- System.arraycopy(
- this.classpaths,
- 0,
- newclasspaths,
- bootclasspathCount,
- pathCount);
-
- if (bootclasspathCount != 0) {
- System.arraycopy(
- bootclasspaths,
- 0,
- newclasspaths,
- 0,
- bootclasspathCount);
- }
- this.classpaths = newclasspaths;
- for (int i = 0, max = this.classpaths.length; i < max; i++) {
- File file = new File(this.classpaths[i]);
- if (!file.exists()) { // signal missing classpath entry file
- this.logger.logIncorrectClasspath(this.classpaths[i]); //$NON-NLS-1$
+ if (extdirsNames.size() == 0) {
+ String extdirsStr = System.getProperty("java.ext.dirs"); //$NON-NLS-1$
+ if (extdirsStr == null) {
+ extdirsNames.add(getJavaHome().getAbsolutePath() + "/lib/ext"); //$NON-NLS-1$
+ }
+ else {
+ StringTokenizer tokenizer = new StringTokenizer(extdirsStr, File.pathSeparator);
+ while (tokenizer.hasMoreTokens())
+ extdirsNames.add(tokenizer.nextToken());
}
}
+
+ /*
+ * Feed extdirsClasspath with the entries found into the directories listed by
+ * extdirsNames.
+ */
+ if (extdirsNames.size() != 0) {
+ File[] directoriesToCheck = new File[extdirsNames.size()];
+ for (int i = 0; i < directoriesToCheck.length; i++)
+ directoriesToCheck[i] = new File((String) extdirsNames.get(i));
+ File[][] extdirsJars = getLibrariesFiles(directoriesToCheck);
+ if (extdirsJars != null) {
+ for (int i = 0, max = extdirsJars.length; i < max; i++) {
+ File[] current = extdirsJars[i];
+ if (current != null) {
+ for (int j = 0, max2 = current.length; j < max2; j++) {
+ FileSystem.Classpath classpath =
+ FileSystem.getClasspath(
+ current[j].getAbsolutePath(),
+ null, 0, null);
+ if (classpath != null) {
+ extdirsClasspaths.add(classpath);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Concatenate classpath entries
+ * We put the bootclasspath at the beginning of the classpath
+ * entries, followed by the extension libraries, followed by
+ * the sourcepath followed by the classpath. All classpath
+ * entries are searched for both sources and binaries except
+ * the sourcepath entries which are searched for sources only.
+ */
+ bootclasspaths.addAll(extdirsClasspaths);
+ bootclasspaths.addAll(sourcepathClasspaths);
+ bootclasspaths.addAll(classpaths);
+ classpaths = bootclasspaths;
+ this.checkedClasspaths = new FileSystem.Classpath[classpaths.size()];
+ classpaths.toArray(this.checkedClasspaths);
if (this.destinationPath == null) {
this.generatePackagesStructure = false;
} else if ("none".equals(this.destinationPath)) { //$NON-NLS-1$
@@ -2190,7 +2393,7 @@
}
this.logger.logCommandLineArguments(newCommandLineArgs);
this.logger.logOptions(this.options);
- this.logger.logClasspath(this.classpaths);
+ this.logger.logClasspath(this.checkedClasspaths);
if (this.repetitions == 0) {
this.repetitions = 1;
}
@@ -2200,6 +2403,83 @@
}
}
+ private void addNewEntry(final int InsideClasspath, final int InsideSourcepath, ArrayList bootclasspaths, ArrayList classpaths,ArrayList sourcepathClasspaths, String currentClasspathName, ArrayList currentRuleSpecs, int mode, String customEncoding) {
+ AccessRule[] accessRules = new AccessRule[currentRuleSpecs
+ .size()];
+ boolean rulesOK = true;
+ Iterator i = currentRuleSpecs.iterator();
+ int j = 0;
+ while (i.hasNext()) {
+ String ruleSpec = (String) i.next();
+ char key = ruleSpec.charAt(0);
+ String pattern = ruleSpec.substring(1);
+ if (pattern.length() > 0) {
+ switch (key) {
+ case '+':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(), -1);
+ break;
+ case '~':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.DiscouragedReference);
+ break;
+ case '-':
+ accessRules[j++] = new AccessRule(pattern
+ .toCharArray(),
+ IProblem.ForbiddenReference);
+ break;
+ default:
+ rulesOK = false;
+ }
+ } else {
+ rulesOK = false;
+ }
+ }
+ if (rulesOK) {
+ AccessRuleSet accessRuleSet = new AccessRuleSet(
+ accessRules, "{0}"); //$NON-NLS-1$
+ FileSystem.Classpath currentClasspath = FileSystem
+ .getClasspath(currentClasspathName,
+ customEncoding, 0, accessRuleSet);
+ if (currentClasspath != null) {
+ if (mode == InsideClasspath) {
+ classpaths.add(currentClasspath);
+ } else if (mode == InsideSourcepath) {
+ if (currentClasspath instanceof ClasspathDirectory) {
+ ((ClasspathDirectory) currentClasspath).mode =
+ ClasspathDirectory.SOURCE;
+ // TODO may consider adding this attribute to other classpath natures
+ }
+ sourcepathClasspaths.add(currentClasspath);
+ } else { // inside bootclasspath
+ bootclasspaths.add(currentClasspath);
+ }
+ } else {
+ this.logger.logIncorrectClasspath(currentClasspathName);
+ // we go on anyway
+ }
+ } else {
+ this.logger.logIncorrectClasspath(currentClasspathName);
+ // we go on anyway
+ }
+ }
+
+ private File javaHomeCache;
+ private boolean javaHomeChecked;
+ private File getJavaHome() {
+ if (!javaHomeChecked) {
+ javaHomeChecked = true;
+ String javaHome = System.getProperty("java.home");//$NON-NLS-1$
+ if (javaHome != null) {
+ javaHomeCache = new File(javaHome);
+ if (!javaHomeCache.exists())
+ javaHomeCache = null;
+ }
+ }
+ return javaHomeCache;
+ }
+
private void disableWarnings() {
Object[] entries = this.options.entrySet().toArray();
for (int i = 0, max = entries.length; i < max; i++) {
@@ -2250,6 +2530,7 @@
// exit?
if (Main.this.systemExitWhenFinished && !Main.this.proceedOnError && (localErrorCount > 0)) {
Main.this.logger.endLoggingSource();
+ Main.this.logger.endLoggingSources();
Main.this.logger.printStats(Main.this);
Main.this.logger.flush();
Main.this.logger.close();
@@ -2311,18 +2592,6 @@
return result;
}
- private int getLength(File[][] libraries) {
- int sum = 0;
- if (libraries != null) {
- for (int i = 0, max = libraries.length; i < max; i++) {
- final File[] currentFiles = libraries[i];
- if (currentFiles != null) {
- sum+= currentFiles.length;
- }
- }
- }
- return sum;
- }
/*
* Low-level API performing the actual compilation
*/
@@ -2342,8 +2611,8 @@
String defaultEncoding = (String) this.options.get(CompilerOptions.OPTION_Encoding);
if ("".equals(defaultEncoding)) //$NON-NLS-1$
- defaultEncoding = null; //$NON-NLS-1$
- return new FileSystem(this.classpaths, this.filenames, defaultEncoding);
+ defaultEncoding = null;
+ return new FileSystem(this.checkedClasspaths, this.filenames);
}
/*
* Low-level API performing the actual compilation
@@ -2355,14 +2624,14 @@
public void outputClassFiles(CompilationResult unitResult) {
if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) {
- Enumeration classFiles = unitResult.compiledTypes.elements();
+ ClassFile[] classFiles = unitResult.getClassFiles();
if (!this.generatePackagesStructure) {
this.destinationPath = extractDestinationPathFromSourceFile(unitResult);
}
if (this.destinationPath != null) {
- while (classFiles.hasMoreElements()) {
+ for (int i = 0, fileCount = classFiles.length; i < fileCount; i++) {
// retrieve the key and the corresponding classfile
- ClassFile classFile = (ClassFile) classFiles.nextElement();
+ ClassFile classFile = classFiles[i];
char[] filename = classFile.fileName();
int length = filename.length;
char[] relativeName = new char[length + 6];
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index 22b7234..7e5dad9 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -14,7 +14,7 @@
#Format: compiler.name = word1 word2 word3
compiler.name = Eclipse Java Compiler
#Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)]
-compiler.version = 0.553, pre-3.1.0 milestone-7
+compiler.version = v_574_R31x, pre-3.1.1 release
compiler.copyright = Copyright IBM Corp 2000, 2005. All rights reserved.
### scanning
@@ -49,6 +49,8 @@
configure.source = source level should be comprised in between ''1.3'' and ''1.5'' (or ''5'' or ''5.0''): {0}
configure.duplicateOutputPath = duplicate output path specification: {0}
configure.duplicateBootClasspath = duplicate bootclasspath specification: {0}
+configure.duplicateExtdirs = duplicate extdirs specification: {0}
+configure.duplicateSourcepath = duplicate sourcepath specification: {0}
configure.invalidDebugOption = invalid debug option: {0}
configure.invalidWarningConfiguration = invalid warning configuration: {0}
configure.invalidWarning = invalid warning: {0}
@@ -92,9 +94,19 @@
\ \n\
\ Classpath options:\n\
\ -cp -classpath <directories and zip/jar files separated by {0}>\n\
-\ specify location for application classes and sources\n\
+\ specify location for application classes and sources. Each\n\
+\ directory or file can specify access rules for types between\n\
+\ ''['' and '']'' (e.g. [-X.java] to deny access to type X)\n\
\ -bootclasspath <directories and zip/jar files separated by {0}>\n\
-\ specify location for system classes\n\
+\ specify location for system classes. Each directory or file can\n\
+\ specify access rules for types between ''['' and '']'' (e.g. [-X.java]\n\
+\ to deny access to type X)\n\
+\ -sourcepath <directories separated by {0}>\n\
+\ specify location for application sources. Each directory can\n\
+\ specify access rules for types between ''['' and '']'' (e.g. [-X.java]\n\
+\ to deny access to type X)\n\
+\ -extdirs <directories separated by {0}>\n\
+\ specify location for extension zip/jar files\n\
\ -d <dir> destination directory (if omitted, no directory is created)\n\
\ -d none generate no .class files\n\
\ -encoding <enc> specify custom encoding for all sources. Each file/directory can override it\n\
@@ -121,13 +133,15 @@
\ charConcat + char[] in String concat\n\
\ conditionAssign possible accidental boolean assignment\n\
\ constructorName + method with constructor name\n\
+\ dep-ann missing @Deprecated annotation\n\
\ deprecation + deprecation outside deprecated code\n\
-\ Deprecated missing @Deprecated annotation\n\
\ emptyBlock undocumented empty block\n\
\ enumSwitch incomplete enum switch\n\
\ fieldHiding field hiding another variable\n\
\ finalBound type parameter with final bound\n\
\ finally + finally block not completing normally\n\
+\ hiding macro for fieldHiding, localHiding, typeHiding and maskedCatchBlock\n\
+\ incomplete-switch same as enumSwitch\n\
\ indirectStatic indirect reference to static member\n\
\ intfAnnotation + annotation type used as super interface\n\
\ intfNonInherited + interface non-inherited method compatibility\n\
@@ -136,27 +150,32 @@
\ maskedCatchBlock + hidden catch block\n\
\ nls string literal lacking non-nls tag //$NON-NLS-<n>$\n\
\ noEffectAssign + assignment without effect\n\
-\ nullCheck + missing or redundant null check\n\
-\ Override missing @Override annotation\n\
+\ null missing or redundant null check\n\
+\ over-ann missing @Override annotation\n\
\ pkgDefaultMethod + attempt to override package-default method\n\
\ semicolon unnecessary semicolon, empty statement\n\
\ serial + missing serialVersionUID\n\
-\ unqualifiedField unqualified reference to field\n\
-\ unchecked + unchecked type operation\n\
-\ unusedArgument unread method parameter\n\
-\ unusedImport + unused import declaration\n\
-\ unusedLocal unread local variable\n\
-\ unusedPrivate unused private member declaration\n\
-\ unusedThrown unused declared thrown exception\n\
-\ unnecessaryElse unnecessary else clause\n\
-\ uselessTypeCheck unnecessary cast/instanceof operation\n\
\ specialParamHiding constructor or setter parameter hiding another field\n\
+\ static-access macro for indirectStatic and staticReceiver\n\
\ staticReceiver + non-static reference to static member\n\
+\ suppress + enable @SuppressWarnings\n\
+\ synthetic-access same as syntheticAccess\n\
\ syntheticAccess synthetic access for innerclass\n\
\ tasks(<tags separated by |>) tasks identified by tags inside comments\n\
\ typeHiding + type parameter hiding another type\n\
+\ unchecked + unchecked type operation\n\
+\ unnecessaryElse unnecessary else clause\n\
+\ unqualified-field-access same as unQualifiedField\n\
+\ unqualifiedField unqualified reference to field\n\
+\ unused macro for unusedArgument, unusedImport, unusedLocal, unusedPrivate and unusedThrown\n\
+\ unusedArgument unread method parameter\n\
+\ unusedImport + unused import declaration\n\
+\ unusedLocal + unread local variable\n\
+\ unusedPrivate + unused private member declaration\n\
+\ unusedThrown unused declared thrown exception\n\
+\ uselessTypeCheck unnecessary cast/instanceof operation\n\
\ varargsCast + varargs argument need explicit cast\n\
-\
+\ warningToken + unhandled warning token in @SuppressWarnings\n\
\ \n\
\ Debug options:\n\
\ -g[:lines,vars,source] custom debug info\n\
@@ -165,10 +184,17 @@
\ -g:none no debug info\n\
\ -preserveAllLocals preserve unused local vars for debug purpose\n\
\ \n\
+\ Ignored options:\n\
+\ -J<option> pass option to virtual machine (ignored)\n\
+\ -X<option> specify non-standard option (ignored)\n\
+\ -X print non-standard options and exit (ignored)\n\
+\ -O optimize for execution time (ignored)\n\
+\ \n\
\ Advanced options:\n\
\ @<file> read command line arguments from file\n\
\ -maxProblems <n> max number of problems per compilation unit (100 by default)\n\
-\ -log <file> log to a file\n\
+\ -log <file> log to a file. If the file extension is ''.xml'', then the log\n\
+\ will be a xml file.\n\
\ -proceedOnError do not stop at first error, dumping class files with problem methods\n\
\ -verbose enable verbose output\n\
\ -referenceInfo compute reference info\n\
diff --git a/org.eclipse.jdt.core/build.ajproperties b/org.eclipse.jdt.core/build.ajproperties
new file mode 100644
index 0000000..debfb00
--- /dev/null
+++ b/org.eclipse.jdt.core/build.ajproperties
@@ -0,0 +1,10 @@
+src.includes = antadapter/,\
+ aspectj/,\
+ batch/,\
+ codeassist/,\
+ compiler/,\
+ dom/,\
+ eval/,\
+ formatter/,\
+ model/,\
+ search/
diff --git a/org.eclipse.jdt.core/build.properties b/org.eclipse.jdt.core/build.properties
index ba3b548..c47d1ad 100644
--- a/org.eclipse.jdt.core/build.properties
+++ b/org.eclipse.jdt.core/build.properties
@@ -35,5 +35,4 @@
jars.compile.order=.,jdtCompilerAdapter.jar
jars.extra.classpath=platform:/plugin/org.apache.ant/lib/ant.jar
src.includes = about.html,\
- schema/,\
- component.xml
+ schema/
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index 97faf17..6355afc 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="IBM">
- <title>JDT/Core Release Notes</title>
+ <title>JDT/Core Release Notes 3.1</title>
<link rel="stylesheet" href="jdt_core_style.css" charset="iso-8859-1" type="text/css">
</head>
<body text="#000000" bgcolor="#FFFFFF">
@@ -36,21 +36,1400 @@
</td>
</tr>
</table>
-
-<a name="v_553"></a>
+<a name="v_574_R31x"></a>
<p><hr><h1>
-Eclipse Platform Build Notes <br>
+Eclipse Platform Build Notes<br>
Java Development Tooling Core</h1>
-Eclipse SDK 3.1M7 - 2?th April 2005
-<br>Project org.eclipse.jdt.core v_553
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_553">cvs</a>).
+Eclipse SDK 3.1.1 - 16th August 2005 <!-- - 3.1.1 RELEASE (R3_1_1) -->
+<br>Project org.eclipse.jdt.core v_574_R31x
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_574_R31x">cvs</a>).
<h2>
What's new in this drop</h2>
<ul>
</ul>
<h3>Problem Reports Fixed</h3>
-<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92059">92059</a>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106964">106964</a>
+[1.5][search] AIOBE in MethodLocator.matchOverriddenMethod
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99903">99903</a>
+[1.5][search] range wrong for package-info
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99662">99662</a>
+[1.5] JavaModel returns inexistent IType for package-info ICompilationUnits
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106936">106936</a>
+[1.5][compiler] Unoptimal lub computation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106865">106865</a>
+[1.5][compiler] capture conversion doesn't handle array types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105284">105284</a>
+[1.5][compiler] Autoboxing: Type mismatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106106">106106</a>
+[1.5][compiler] Compiler error with Arrays.asList in Java 5 mode?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105531">105531</a>
+[1.5][compiler] ecj from CVS generates spurious incomprehensible error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106514">106514</a>
+[1.5][compiler] Improve diagnostic on bound mismatch for GenericTypeTests.test79
+
+
+<a name="v_573_R31x"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1.1 - 11th August 2005
+<br>Project org.eclipse.jdt.core v_573_R31x
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_573_R31x">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Plug-in version ID got promoted to "3.1.1".
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106403">106403</a>
+PublicScanner returns EOF late
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=105635">105635</a>
+incorrect parsing of field declarations with generic types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=106297">106297</a>
+[1.5][compiler] new A<X>().new B(){}
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104780">104780</a>
+TVT 3.1: TCT 386 - wrong description for option FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100041">100041</a>
+[javadoc][dom] Wrong positions when javadoc comment inside method declaration
+
+
+<a name="v_572_R31x"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1.1 - 3rd August 2005
+<br>Project org.eclipse.jdt.core v_572_R31x
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_572_R31x">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104664">104664</a>
+[compiler] repeat mode is broken in the batch compiler
+
+<a name="v_571a_R31x"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1.1 - 27th July 2005
+<br>Project org.eclipse.jdt.core v_571a_R31x
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_571a_R31x">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104738">104738</a>
+[1.5][compiler] Enclosing method attribute is generated for member type of a local type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104649">104649</a>
+[1.5][compiler] method type variable: inference broken for null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104655">104655</a>
+[1.5] inconsistent compiler behavior in generic methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104551">104551</a>
+[1.5][compiler] Method override checks fail with raw subtype and type variable as type bound
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104492">104492</a>
+[AST]java.lang.ClassCastException: org.eclipse.jdt.core.dom.PrimitiveType
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103485">103485</a>
+[1.5][compiler] compiler: wrongfully accepted method call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103994">103994</a>
+[1.5][compiler] Internal compiler error while overriding bootstrap class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103528">103528</a>
+[1.5][compiler] compiler allows invalid assignment with method type parameter and nested wildcards
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104082">104082</a>
+[1.5][compiler] 1.5 source code gets internal eclipse null pointer error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=104167">104167</a>
+[1.5][compiler] incorrect 'unread field' diagnosis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103320">103320</a>
+Method-local subtype with instance initializer break JDOM
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103636">103636</a>
+JDT compiler produces invalid XML
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103227">103227</a>
+[1.5][compiler] VerifyError in case of a parametrized anonymous class inside a static inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103472">103472</a>
+[1.5][compiler] Should detect incompatible super interfaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102650">102650</a>
+[ast rewrite] Removing all TYPE_PARAMETERS_PROPERTY values in a derived type gives incompilable code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103148">103148</a>
+[1.5][assist] Code completion breaks if using static method generics ( Class.<T>staticMethod(params) )
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91426">91426</a>
+[Markers] Java task tags in Task View don't have configured priority
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100772">100772</a>
+[1.5][search] Search for declarations in hierarchy reports to many matches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100695">100695</a>
+[1.5][search] Renaming a field of generic array type has no effect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=103023">103023</a>
+[1.5][compiler] StackOverflow inferring type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102778">102778</a>
+Scrapbook page doesn't work with enhanced for statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101283">101283</a>
+[1.5][javadoc] Javadoc validation raises missing implementation in compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100868">100868</a>
+Code assist does not recommend methods in anonymous enum subclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101456">101456</a>
+Proposals and Open Declaration fail with NPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101387">101387</a>
+[1.5][compiler] Incorrect Cycle detected in type hierarchy error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97326">97326</a>
+[dom] ITypeBinding#isFromSource() is always false for type variables, wildcards, and capture types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100153">100153</a>
+[1.5][compiler] Bound check failure on recursive formal bound
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100808">100808</a>
+[assist] Wrong replace range for package proposals if there is no line termination
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98532">98532</a>
+[1.5][compiler] Spurious 'type parameter T is hiding the type T' warning for static nested classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100797">100797</a>
+editor general failure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100043">100043</a>
+[1.5][compiler] false compiler error on ?: ternary operator with boxing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102181">102181</a>
+[1.5][compiler] Generic varargs are built with incorrect array type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102305">102305</a>
+Error in JDT Core during reconcile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=102213">102213</a>
+[1.5][compiler] enum constants cannot be referenced inside enum constants initializer
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101955">101955</a>
+NullPointerException after invoking extract method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97220">97220</a>
+Should not issue nls warning for annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101885">101885</a>
+[mode] sort operation doesn't set the RELATIVE_ORDER for enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101247">101247</a>
+[formatter] Fails to format some labelled statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101713">101713</a>
+[1.5][compiler] Access to static fields within enum constructors inconsistent with javac
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101779">101779</a>
+[1.5][compiler] VerifyError using -- operator on unboxed generic Integer type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101208">101208</a>
+[compiler] instanceof check cannot be unnecessary on null values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100619">100619</a>
+[1.5][compiler] Incorrect duplicate bound diagnosis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94759">94759</a>
+[1.5][compiler] @Override doesn't report an error inside interface when specified for clone() method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98538">98538</a>
+[1.5][compiler] Inference broken for subtypes of subtypes of F-bounded types
+
+<a name="v_570"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC4 - 27th June 2005 - 3.1 RELEASE (R3_1)
+<br>Project org.eclipse.jdt.core v_570
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_570">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101453">101453</a>
+java.lang.UnsupportedOperationException: Operation only supported in JLS2 AST
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101794">101794</a>
+[1.5][compiler] Compiling Classpath classes results in bad class file
+
+
+<a name="v_569"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC4 - 24th June 2005 - 3.1 RELEASE (R3_1)
+<br>Project org.eclipse.jdt.core v_569
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_569">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101613">101613</a>
+Performance regressions in Open Type Hierarchy performance test
+
+
+<a name="v_568"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC4 - 23rd June 2005
+<br>Project org.eclipse.jdt.core v_568
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_568">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101426">101426</a>
+[search] Search doesn't work with imported plugin
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101120">101120</a>
+Cannot generate an executable of the batch compiler using gcj 3.4.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100631">100631</a>
+Internal compiler error in 3.1RC2
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101230">101230</a>
+[compiler] Internal compiler error when labeled statement processing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101022">101022</a>
+[search] JUnit Test Runner on folder runs tests outside directory
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=101019">101019</a>
+RC3: Type Hierarchy does not find implementers/extenders of inner class/interface in other project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100009">100009</a>
+[assist] Content assist uses generic parameter name arg0 instead of real name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100584">100584</a>
+[1.5][dom] NPE when selecting a faulty member type following a generic type reference
+
+<a name="v_567"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC3 - 17th June 2005 - 3.1 RELEASE CANDIDATE 3
+<br>Project org.eclipse.jdt.core v_567
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_567">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100519">100519</a>
+[1.5][compiler] generic parameter and qualified access seems to confuse each other
+
+
+<a name="v_566"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC3 - 16th June 2005
+<br>Project org.eclipse.jdt.core v_566
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_566">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100421">100421</a>
+[1.5][compiler] chain of generics-extends confuse compiler
+
+
+<a name="v_565"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC3 - 16th June 2005
+<br>Project org.eclipse.jdt.core v_565
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_565">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99654">99654</a>
+[5.0] JavaModel returns both IClassFile and ICompilationUnit for package-info.java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100393">100393</a>
+Defaults for compiler errors/warnings settings
+
+<a name="v_564"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC3 - 16th June 2005
+<br>Project org.eclipse.jdt.core v_564
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_564">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99606">bug 99606</a> required the index version to be incremented.
+ Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100302">100302</a>
+StackOverflowError during completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99606">99606</a>
+Subtype not found if parameterized on inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100293">100293</a>
+1.5 compiler - Methods using non-generic inner types of concreted generic classes generate wrong signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98322">98322</a>
+[compiler] ParameterizedTypeBinding should not have AccGenericSignature set when no type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99978">99978</a>
+MalformedTreeException on Inline Method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100128">100128</a>
+[1.5][compiler] StackOverflow compiling GNU Classpath generics branch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100142">100142</a>
+CCE when calling ITypeBinding#getJavaElement() on char[][]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100147">100147</a>
+[1.5][compiler] NPE when reporting an error on an unsafe type conversion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100062">100062</a>
+[formatting] Code formatter is broken on test case from bug 99999
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100162">100162</a>
+java.lang.VerifyError is produced by Eclipse Java compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99428">99428</a>
+[1.5][compiler] enum classes created without final accessFlag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99999">99999</a>
+[1.5][compiler] AIOOBE with generics + nested classes + arrays
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99686">99686</a>
+IAE in Util#scanTypeBoundSignature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100149">100149</a>
+[1.5][compiler] Raw type upper bounds should be raw types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99927">99927</a>
+NPE in ParameterizedTypeBinding.initialize
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100138">100138</a>
+[doc] Confusing documentation in Project Configuration tutorial
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99915">99915</a>
+[search] Open Type: not yet saved types not found if case-sensitve name is entered
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=100007">100007</a>
+[1.5][compiler] ClassCastException using array object as generic type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99600">99600</a>
+[search] Java model exception on "Move to new file" on inner type with inner type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99982">99982</a>
+[DOM] Wrong positions for boolean[] type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99811">99811</a>
+NPE during content assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99629">99629</a>
+Error while entering expression in change variable value dialog
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99922">99922</a>
+[1.5][compiler] NPE in compiler for Arrays.asList(3, 3.1);
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98378">98378</a>
+[search] Can't find declarations in hierarchy of interface.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97614">97614</a>
+[1.5][search] Refactoring: renaming of field of a (complex) parametrized type does not replace all occurrences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97547">97547</a>
+[search] Package search does not find references in member types import clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96950">96950</a>
+[search] Code assist proposes non accessible types into completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99510">99510</a>
+isCastCompatible seems to need capture bindings now to answer correct results
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99608">99608</a>
+IMethodBinding#overrides returns false on overridden method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99901">99901</a>
+[select] AIOOBE when selecting package reference in import statement
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99282">99282</a>
+[1.5][compiler] Enum / Switch method is not initialized in a thread safe way
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=52921">52921</a>
+[formatting] Javadoc formatting: extra newline with [pre]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99507">99507</a>
+[javadoc] Infinit loop in DocCommentParser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99397">99397</a>
+Typo in CompletionProposal#isConstructor()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99553">99553</a>
+[1.5][compiler] Parameterized class nested statically inside another parameterized type causes compile errors when used in method signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99355">99355</a>
+extract method trips up with generics and final variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99469">99469</a>
+[1.5][compiler] NPE compiling code with unknown annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99375">99375</a>
+Compiler error using Annotations
+
+<a name="v_563"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC2 - 10th June 2005 - 3.1 RELEASE CANDIDATE 2
+<br>Project org.eclipse.jdt.core v_563
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_563">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99260">99260</a>
+[1.5][compiler] Bad bytecode generated with varargs + generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98331">98331</a>
+[1.5][compiler] Casting Conversion needs to check all supertypes for conflicts
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99106">99106</a>
+[1.5][compiler] Ambiguous method error because methods don't override in eclipse
+
+
+<a name="v_562"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC2 - 9th June 2005
+<br>Project org.eclipse.jdt.core v_562
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_562">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97487">97487</a>
+[call hierarchy] Call Hierarchy Fails in mounted classes with attached src files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97524">97524</a>
+[prefs] Importing preferences with user library doesn't recreate jar entries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99142">99142</a>
+Exception when shutting down quickly after starting
+
+<a name="v_561"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC2 - 9th June 2005
+<br>Project org.eclipse.jdt.core v_561
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_561">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The build state version number has changed. A full build of all projects in the workspace will be triggered upon
+ startup if autobuild is on, or on the next build if autobuild is off.</li>
+<li>The new list of supported warning tokens for the @SuppressWarnings annotation is:
+<ul>
+<li><b><font color="red">all</font></b> : any warning</li>
+<li><b>boxing</b> : autoboxing conversion</li>
+<li><b><font color="red">dep-ann</font></b> : missing @Deprecated annotation</li>
+<li><b><font color="red">deprecation</font></b> : deprecation outside deprecated code</li>
+<li><b>incomplete-switch</b> : incomplete enum switch (<i>enumSwitch</i>)</li>
+<li><b>hiding</b> :
+<ol><li>field hiding another variable (<i>fieldHiding</i>)</li>
+<li>local variable hiding another variable (<i>localHiding</i>)</li>
+<li>type parameter hiding another type (<i>typeHiding</i>)</li>
+<li>hidden catch block (<i>maskedCatchBlock</i>)</li>
+</ol>
+</li>
+<li><b><font color="red">finally</font></b> : finally block not completing normally</li>
+<li><b>static-access</b> :
+<ol>
+<li>indirect reference to static member (<i>indirectStatic</i>)</li>
+<li>non-static reference to static member (<i>staticReceiver</i>)</li>
+</ol>
+</li>
+<li><b>nls</b> : string literal lacking non-nls tag //$NON-NLS-<n>$</li>
+<li><b><font color="red">serial</font></b> : missing serialVersionUID</li>
+<li><b>unqualified-field-access </b>: unqualified reference to field (<i>unQualifiedField</i>)</li>
+<li><b><font color="red">unchecked</font></b> : unchecked type operation</li>
+<li><b>unused</b> :
+<ol>
+<li>unread method parameter (<i>unusedArgument</i>)</li>
+<li>unread local variable (<i>unusedLocal</i>)</li>
+<li>unused private member declaration (<i>unusedPrivate</i>)</li>
+<li>unused declared thrown exception (<i>unusedThrown</i>)</li>
+</ol>
+</li>
+<li><b>synthetic-access</b> : synthetic access for innerclass (<i>syntheticAccess</i>)</li>
+</ul>
+<p>NOTE: <blockquote>All other warning tokens are not longer supported by @SuppressWarnings;
+considering that for some diagnosis, it is simpler to just fix the code than silence some warning.
+In <i>Italic</i> the old warning token is specified.
+<br>Warning tokens also supported by javac are in <font color="red">red</font> (also see <a href="http://www.javac.info/doc?n=JavaCompiler.WarningTokens">declared warning tokens</a>).
+</blockquote></p>
+</li>
+<li>CodeAssist: added a new API CompletionProposal#isConstructor() to distinguish method and constructor proposal</li>
+<li>Access rules file patterns have been changed to ignore the file extension. This allow easy switching from a source project
+ to a binary project. Thus <code>"com/test/X.java"</code> is now an invalid access rule pattern, and
+ <code>"com/test/X"</code> is a valid access rule pattern.</li>
+<li>
+Following batch compiler options default value have been changed from "ignore" to "warning":
+<ul>
+<li>unusedLocal (unread local variable)</li>
+<li>unusedPrivate (unused private member declaration)</li>
+<li>fieldHiding (field hiding another variable)</li>
+<li>localHiding (local variable hiding another variable)</li>
+</ul>
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76530">76530</a>)
+</li>
+<li>Compiler optional diagnosis for unused private members got generalized to also flag unused
+members of local types.
+</li>
+<li>Compiler no longer reports as unchecked the situation where a method of a raw type is invoked,
+and only the return type got altered by raw conversion (also see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85815">85815</a>).
+This change is motivated to better match the language spec 3rd edition.</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97087">bug 97087</a> required the index version to be incremented.
+ Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99138">99138</a>
+NPE in RawTypeBinding.computeUniqueKey(..) for raw type inside anonymous parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93975">93975</a>
+[1.5][syntax] Poor recovery when extra semicolon in annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93208">93208</a>
+[dom] CompilationUnit.rewrite throws AssertionFailedException with legal AST (bug in recoding ast modifications)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97440">97440</a>
+[1.5][compiler] StackOverflow compiling heavily generic code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99104">99104</a>
+Startup job displayed as "Initializing the Java d...ent tooling"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=99084">99084</a>
+Formatter error when generic method has an argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98892">98892</a>
+[compiler] Eclipse compiler generates code that calls the finally block twice
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98969">98969</a>
+Builder didn't find state for prereq project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96586">96586</a>
+[1.5][compiler] Invalid cycle detected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98954">98954</a>
+Javadoc of ITypeBinding#getErasure() is wrong for array types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98504">98504</a>
+[1.5][compiler] Compiler difference between javac and jdt?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96763">96763</a>
+[1.5][search] Search for method declarations does not find overridden method with different signature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96761">96761</a>
+[1.5][search] Search for declarations of generic method finds non-overriding method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98228">98228</a>
+[1.5][compiler] regression - incorrect handling of generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98720">98720</a>
+[preferences] classpath variables are not exported if the session is closed and restored
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98906">98906</a>
+No rebuild after upgrade
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98711">98711</a>
+no way to distinguish constructor from method proposals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98434">98434</a>
+A non-1.5 project with 1.5 projects in the classpath does not show methods with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98750">98750</a>
+[dom] Java DOM Parser finding syntax Problems when parsing Annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90619">90619</a>
+[1.5][compiler] Cannot implement generified interface with erased method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98500">98500</a>
+[1.5] Internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98488">98488</a>
+NPE while computing a key for a paramterized type binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97087">97087</a>
+[1.5][search] Can't find reference of generic class's constructor.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93668">93668</a>
+Search indexes not rebuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98473">98473</a>
+AST binding: type variable reports as 'isTopLevel'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98364">98364</a>
+[1.5][compiler] Compiler allowing invalid generic interface inheritance
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85815">85815</a>
+[1.5] warn when raw iterator is used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93377">93377</a>
+[1.5][compiler] Multiple auto-build failures when using generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79309">79309</a>
+Nested interfaces aren't resolved correctly in import (with "Open Declaration" / F3)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96765">96765</a>
+Code completion does not work in enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98483">98483</a>
+IMethodBinding.override does not compare method names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98115">98115</a>
+Field completion failed to propose a field declared into an innerclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93789">93789</a>
+[1.5][compiler] Compiler incorrectly allows static declarations in enum constants.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98396">98396</a>
+[1.5][compiler] Casting Conversion ignores second bound of Type Variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98383">98383</a>
+[1.5][compiler] ClassCastException attempting to cast from intersection type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97322">97322</a>
+[search] Search for method references sometimes reports potential match with differing argument count
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94160">94160</a>
+[1.5][search] Generic method in superclass does not exist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91061">91061</a>
+[1.5][compiler] Static reference to outer type variable should not be allowed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97108">97108</a>
+[1.5][compiler] NullPointerException encountered while running Java Builder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98259">98259</a>
+NPE computing ITypeBinding#getKey()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93536">93536</a>
+[1.5] Internal compiler generating error on code that javac accepts
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97606">97606</a>
+[1.5][search] Raw type reference is reported as exact match for qualified names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96424">96424</a>
+[search] SearchParticipant sets containerPath to documentPath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97542">97542</a>
+ASTParser#createASTs does not correctly resolve bindings in working copies
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94898">94898</a>
+[1.5] errors in ambiguous method invocation detection
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94754">94754</a>
+[1.5][compiler] Ambiguous method call is not detected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84035">84035</a>
+[1.5][compiler] Ambiguous method call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76530">76530</a>
+[options] Warn about unused local variables and private members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98091">98091</a>
+[1.5][compiler] @SuppressWarnings("assertIdentifier") cannot be applied
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94907">94907</a>
+[assist] missing keyword completions for generic signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84001">84001</a>
+[select] Renaming of class with internal classes fails.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94641">94641</a>
+Code assist does not display parameters for constructor with type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96991">96991</a>
+[1.5][compiler] Annotation attribute should be able to reference field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96713">96713</a>
+[1.5][compiler] Inconsistency with Sun JDK
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95684">95684</a>
+[1.5][compiler] Type handling on concrete inner class of super class is incorrect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97273">97273</a>
+Illegal argument exception in Signature#getTypeSignatureKind
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98165">98165</a>
+Wrong source range for ConditionalExpression with casted target in FieldAccess as expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96085">96085</a>
+[1.5][compiler] problems with inner classes and generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98139">98139</a>
+Java Code Formatter is severely confused by following code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98079">98079</a>
+[1.5][compiler] incorrect Bound mismatch compilation error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97860">97860</a>
+[1.5][assist] All current proposals while completing after a type parameter results in a compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82560">82560</a>
+[assist] Completion fails on parameterized generic method call
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98086">98086</a>
+[1.5][dom] CU still have problems even with @SuppressWarnings("all")
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=98037">98037</a>
+[Java Editor Templates] Templates with multiple lines are inlined when used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96258">96258</a>
+Bogus build path errors caused by multiple project import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97902">97902</a>
+NPE on Open Declaration on reference to generic type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80432">80432</a>
+Code Assist box exhibits strange behavior in an endless for loop
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96944">96944</a>
+[1.5][assist] shoud not suggest type parameters after new
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97801">97801</a>
+[1.5][codeassist] The type of the class literal must be parameterized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85384">85384</a>
+[1.5][assist] "extends" not proposed when writing method declarations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97219">97219</a>
+[1.5] eclipse does not detect ambiguous method invocation errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97744">97744</a>
+[compiler][ant adapter] NPE when verbose = true and destDir not specified
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97480">97480</a>
+[1.5][compiler] incorrect error on some calls to raw Map.Entry.setValue
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97809">97809</a>
+Ambiguous method reference wrongly reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97814">97814</a>
+Incorrect resolved information on hover
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97841">97841</a>
+[1.5][dom] null binding for ClassInstanceCreation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90916">90916</a>
+CCE in SourceTypeConverter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97466">97466</a>
+NPE in SourceTypeConverter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97307">97307</a>
+[5.0][typing] completion for "import static" deletes all source before
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97459">97459</a>
+CCE during reconcile and AST creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97800">97800</a>
+[1.5][compiler] Cast type shouldn't be used in generic method argument inference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95349">95349</a>
+Access rule pattern matching should ignore file extension
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97161">97161</a>
+[1.5][compiler] Internal compiler error java.lang.NullPointerException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97303">97303</a>
+[1.5][compiler] Cannot convert when inferring list of inner parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97272">97272</a>
+Export preferences offers "all" button, does not export classpath variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96794">96794</a>
+Polishing disassembler output
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97275">97275</a>
+method reference should not contain type variable anymore
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97187">97187</a>
+[rendering] Shows Single Char for primitve Types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96918">96918</a>
+Code Assist - suggest extends and super in the context of a wildcard type argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97190">97190</a>
+Incorrect handling of large long values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97247">97247</a>
+ArrayIndexOutOfBoundsException in ClassFile.addSyntheticSwitchTable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76155">76155</a>
+[options] Unused code warning for unused methods in anonymous inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97224">97224</a>
+[polish][compiler] Inconsistent error message for non-visible field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95481">95481</a>
+[1.5] NPE in TypeVariableBinding.checkBounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65748">65748</a>
+[type hierarchy] Hierarchy view fails to pick up class modifier change
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96633">96633</a>
+getJavaElement returns null for Object[] array binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96605">96605</a>
+JDTCompilerAdapter should allow a log without all verbose information
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96858">96858</a>
+IllegalArgumentException in Signature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97164">97164</a>
+classpath variables lost when upgrading from M7 to RC1
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=97139">97139</a>
+eclipse 3.1RC1 compiler crash for project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96974">96974</a>
+[5.0] @SuppressWarnings({"nls"}) does not work for unexternalized strings
+
+<a name="v_560"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC1 - 26th May 2005 - 3.1 RELEASE CANDIDATE 1
+<br>Project org.eclipse.jdt.core v_560
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_560">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96646">96646</a>
+[1.5][compiler] VerifyError - Generics and Interfaces - "Wrong return type in function"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96631">96631</a>
+NPE in Annotation on empty ArrayInitializer
+
+
+<a name="v_559"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC1 - 26th May 2005
+<br>Project org.eclipse.jdt.core v_559
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_559">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95638">95638</a>
+[1.5][compiler] Possibly incorrect Bounds Mismatch errors for complicated bounds
+
+
+<a name="v_558"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1RC1 - 26th May 2005
+<br>Project org.eclipse.jdt.core v_558
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_558">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The Code Assist option CODEASSIST_HIDE_RESTRICTED_REFERENCES is replaced by
+CODEASSIST_FORBIDDEN_REFERENCE_CHECK and CODEASSIST_DISCOURAGED_REFERENCE_CHECK
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94403">94403</a>).
+</li>
+<li> Code Assist suggest all member types when completion token is a single name.
+<pre>
+Y<complete here> // p.q.X.Y is proposed.
+</pre>
+As all member types are proposed, code assist does not propose types of the wrong kind.
+Only classes are proposed inside an extends clause, only interfaces inside an implements clause
+and only annotations in annotation reference (It was necessary before to be able to propose
+a top level type which contains these types).<br>
+Note: To re-enabled quickly the old behaviors, change the value of Completion.PROPOSE_MEMBER_TYPES.
+</li>
+<li>Added API <code>JavaCore#initializeAfterLoad(IProgressMonitor)</code> to allow
+ a client to force the initialization of internal structures.
+</li>
+<li>Default value for <code>COMPILER_PB_MISSING_JAVADOC_COMMENTS_OVERRIDING</code> and
+ <code>COMPILER_PB_MISSING_JAVADOC_TAGS_OVERRIDING</code> JavaCore options have been changed from "enabled" to "disabled".<br>
+ (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96270">96270</a>).
+</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75816">bug 75816</a> required the index version to be incremented.
+ Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>
+Duplicate names are not allowed in classpath entry extra attributes.<br>
+Javadoc comment of each <code>JavaCore.new*Entry</code> method have been updated to clearly specify this behavior:
+<pre>
+ * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+ * this entry. If no extra attributes are provided, an empty array must be passed in.
+ * Note that this list should not contain any duplicate name.
+</pre>
+<code>JavaConventions.validateClasspathEntry(IJavaProject,IClasspathEntry,boolean,boolean)</code> has been modified
+to verify this point. It now returns an invalid status (<code>new IJavaStatus(IJavaModelStatusConstants.NAME_COLLISION,...)</code>)
+when duplicate names are found in extra attributes.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93119">93119</a>
+code assist: proposals for wildcard types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95505">95505</a>
+Can not use code completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96698">96698</a>
+org.eclipse.jdt.core.dom.VariableBinding.getUnresolvedJavaElement produce ClassCastException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88364">88364</a>
+compiler options
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94267">94267</a>
+[1.5][select] Selecting type parameter in binary answer match on line 0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96642">96642</a>
+CCE in SourceMapper.computeAllRootPaths(..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87362">87362</a>
+BindingKey#internalToSignature() should return the field's type signature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94404">94404</a>
+[model] Disallow classpath attributes with same key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92398">92398</a>
+[compiler] Leverage access rule support in batch compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96588">96588</a>
+Rename Signature#removeCaptureFromMethod(...) to removeCaptureFrom(..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96410">96410</a>
+Incorrect information in selection resolved key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75816">75816</a>
+[search] Call Hierarchy does not find calls to the constructor of java.util.HashMap.Entry [call hierarchy]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95167">95167</a>
+[content assist] Spurious "Access restriction" error during code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95580">95580</a>
+CreateField on IType doesn't work if the type is an enum type that has enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95963">95963</a>
+(3.1M7) Compiler error when parameterizing with missing inner type.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96134">96134</a>
+Internal error for odd (probably illegal) class declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96464">96464</a>
+[assist] JavaCorePreferenceInitializer does not initialized CODEASSIST_DISCOURAGED_REFERENCE_CHECK
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96414">96414</a>
+Javadoc of ASTParser#setCompilerOptions(..): mention that setProject(..) resets options
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95933">95933</a>
+Refining a generic method causes AbstractMethodError
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94897">94897</a>
+[1.5] Compiler does not reject class with two erasure-equivalent methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96213">96213</a>
+Eclipse 3.1M7 - Field completion stack overflow
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96401">96401</a>
+jdt.core tests pass, but fill the .log
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96439">96439</a>
+Hierarchy not refreshed if adding a dependent project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82852">82852</a>
+"Searching for errors in <project>" running unit tests from package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95154">95154</a>
+Missing package.html files for API packages
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96387">96387</a>
+Schemas for extension points are inaccurate
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93249">93249</a>
+Code assist doesn't propose full method stub
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94878">94878</a>
+Configuration details is large, containing many prefs for PDE and JDT classpath containers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96270">96270</a>
+[javadoc] Missing Javadoc comment: 'check overriding..' should be 'off' by default
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96300">96300</a>
+Use the line separator platform preference for new files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94303">94303</a>
+import static adds annoying semicolon
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83716">83716</a>
+[search] refs to 2-arg constructor on Action found unexpected matches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=96071">96071</a>
+Javadoc for IJavaProject.findType(String ) is not consistant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94903">94903</a>
+Error setting method breakpoint in 1.5 project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88395">88395</a>
+[1.5][compiler] Binary compat problem with enum/switch codegen
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95727">95727</a>
+ITypeBinding#getJavaElement() returns a ResolvedSourceField for an anonymous class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95909">95909</a>
+Error with static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95794">95794</a>
+[1.5][search] Search for all occurrences does not find references in static imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95911">95911</a>
+[5.0][dom] Wrong node range for variable declaration fragment containing anonymous class declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93941">93941</a>
+Classpath initialization on shutdown
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93731">93731</a>
+JDT core job still running after shutdown.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89849">89849</a>
+[1.5][assist] Completion in switch proposes already written enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91670">91670</a>
+package-info.java is not being correctly compiled
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93880">93880</a>
+[1.5][javadoc] Source range of PackageDeclaration does not include Javadoc child
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93254">93254</a>
+[assist] ClassCastException when complete annotation type ref
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95760">95760</a>
+[1.5][search] MatchLocator does not compile against 5.0 JRE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93668">93668</a>
+Search indexes not rebuild
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95748">95748</a>
+SourceMapper should not write timing info to stdout
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92555">92555</a>
+Code assist in Annotations suggests non-annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92733">92733</a>
+[assist] Classes suggested in implements clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94965">94965</a>
+[assist] code assist should suggest inner types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92937">92937</a>
+Need API: JavaCore#initializeAfterLoad()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90215">90215</a>
+[1.5] Enums implementing generic interfaces can compile incorrectly.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95244">95244</a>
+performance optimization in SourceMapper.computeAllRootPaths
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91615">91615</a>
+Wrong class opened by debugger/"Open Type"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=39856">39856</a>
+External jar's timestamps should be persisted accross sessions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89632">89632</a>
+Exception when trying to evaluate in Snippet Editor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95538">95538</a>
+Operation not supported in JLS2 AST from resolving MethodBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95521">95521</a>
+[1.5][javadoc] validation with @see tag not working for generic method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95286">95286</a>
+[1.5][javadoc] package-info.java incorrectly flags "Missing comment for public declaration"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95388">95388</a>
+[code manipulation] NPE sorting members
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94150">94150</a>
+[1.5][javadoc][enum] javadoc is always null for EnumConstantDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94653">94653</a>
+[1.5][select] Selection on invalid raw member type should still surface raw type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94092">94092</a>
+ASTParser#createASTs(..) restores wrong bindings from capture keys
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88719">88719</a>
+UserLibrary.serialize /createFromString need support for access restriction / attributes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89937">89937</a>
+[1.5][compiler] Annotation attribute should not be able to reference field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93891">93891</a>
+Restricted UIPlugin is in my code assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93905">93905</a>
+Batch compiler - add a timestamp to log files
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95262">95262</a>
+ASTParser fails with K_CLASS_BODY_DECLARATIONS
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95211">95211</a>
+[api] stale J2SE5 comment in IDOMImport
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95431">95431</a>
+Code formatter fails to format this code
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95394">95394</a>
+Problem resolving types for Assignment ("+=") on 3.1M7
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83034">83034</a>
+[1.5][compiler] method on A<D,?> not applicable for argument <?>
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87550">87550</a>
+[1.5] [compiler] The method in the type is not applicable for the arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95021">95021</a>
+[1.5][compiler] incorrectly inferred method type parameters bug in 3.1M6?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91588">91588</a>
+Delete CVS project and then add as source project leads to duplicate Open Type entries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73969">73969</a>
+Full build on startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80118">80118</a>
+[search] OutOfMemoryError while searching for Test class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87749">87749</a>
+different IMethodBindings of generic method have equal getKey()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94398">94398</a>
+Error attempting to find References
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93408">93408</a>
+ITypeBinding#isEqualTo(..) does not resolve type variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94389">94389</a>
+[search] InvocationTargetException on Rename
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79990">79990</a>
+[1.5][search] Search for method declaration doesn't find method with instantiated type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=95066">95066</a>
+[1.5][compiler] Wrong Cast Allowed
+
+
+<a name="v_557"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M7 - 12th May 2005 - 3.1 MILESTONE 7 / 3.1 RELEASE CANDIDATE 0
+<br>Project org.eclipse.jdt.core v_557
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_557">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94308">94308</a>
+[1.5][compiler] @SuppressWarnings("deprecation") does not suppress warnings from javadoc
+
+
+<a name="v_556"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M7 - 12th May 2005
+<br>Project org.eclipse.jdt.core v_556
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_556">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Enabled by default the optional compiler diagnosis to signal unhandled warning tokens in <code>@SuppressWarnings</code> annotations.
+Note that this warning can itself be turned off using @SuppressWarnings("warningToken").
+<pre>
+* COMPILER / Reporting Unhandled Warning Token for @SuppressWarnings
+* When enabled, the compiler will issue an error or a warning when encountering a token
+* it cannot handle inside a @SuppressWarnings annotation.
+* - option id: "org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"
+* - possible values: { "error", "warning", "ignore" }
+* - default: "warning"
+</pre>
+</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94718">bug 94718</a> required the index version to be incremented.
+ Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94928">94928</a>
+[1.5][compiler] NPE in ParameterizedGenericMethodBinding generated by making method generic
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93727">93727</a>
+Code Formatter fails with Method Parameter Annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93075">93075</a>
+Invalid source ranges for nested ParameterizedTypes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92360">92360</a>
+type binding with isWildcardType() == true should not have isClass() == true
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94168">94168</a>
+Java annotation is missing in EnumConstantDeclaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94867">94867</a>
+[1.5][compiler] Annotation method should tolerate empty array default value
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94747">94747</a>
+[1.5][compiler] Error message is not optimal
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94718">94718</a>
+[1.5][search][annot] Find references in workspace breaks on an annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94644">94644</a>
+[1.5][compiler] Non-static member type of raw type should be raw
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94206">94206</a>
+CCE in BindingKeyResolver when restoring array type of method type parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94260">94260</a>
+[Preferences] preference option missing in Compiler Settings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94262">94262</a>
+[1.5] non static class must not be visible through static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93904">93904</a>
+Batch compiler -log option broken for some values
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87627">87627</a>
+[1.5][search] references to type variable yield non-existent elements in search view
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93588">93588</a>
+[compiler] java.lang.VerifyError: Looks similar to 60040 but is happening on current release
+
+
+<a name="v_555"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M7 - 9th May 2005
+<br>Project org.eclipse.jdt.core v_555
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_555">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Code Assist provide the enclosing type reference when cursor is inside a type argument
+and the completion token is empty (in the same way as method calls).
+<pre>
+p.q.X<<complete here>> // p.q.X<T,U> is proposed.
+p.q.X<Object, <complete here>> //p.q.X<T,U> is proposed
+</pre>
+</li>
+<li> Code Assist provide the enclosing annotation reference when completion is inside an annotation argument
+and the completion token is empty (in the same way as method calls).
+<pre>
+@Annot(<complete here>) // p.Annot is proposed.
+@Annot(foo1=0, <complete here>) // p.Annot is proposed.
+</pre>
+</li>
+<li> In 5.0 compliant mode, changed local inner type naming convention to reflect JLS 13.1 (3rd edition).
+As a consequence, instead of generating a file named <code>X$1$A.class</code>, it will simply be <code>X$1A.class"</code>.
+</li>
+<li> Added optional compiler diagnosis to signal unhandled warning tokens in <code>@SuppressWarnings</code> annotations.
+Note that this warning can itself be turned off using @SuppressWarnings("warningToken").
+<pre>
+* COMPILER / Reporting Unhandled Warning Token for @SuppressWarnings
+* When enabled, the compiler will issue an error or a warning when encountering a token
+* it cannot handle inside a @SuppressWarnings annotation.
+* - option id: "org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"
+* - possible values: { "error", "warning", "ignore" }
+* - default: "ignore"
+</pre>
+</li>
+<li> Added compiler option to control whether @SuppressWarning annotations are active or not.
+By disabling them, one can quickly revive all hidden warnings.
+<pre>
+* COMPILER / Determine whether @SuppressWarnings is effective
+* When enabled, the @SuppressWarnings annotation can be used to suppress some compiler warnings.
+* When disabled, all @SupressWarnings annotations are ignored; i.e., warnings are reported.
+* - option id: "org.eclipse.jdt.core.compiler.problem.suppressWarnings"
+* - possible values: { "enabled", "disabled" }
+* - default: "enabled"
+</pre>
+</li>
+<li> Added API on <code>CorrectionEngine</code> for computing the warning token corresponding to an optional warning ID.
+<pre>
+/**
+ * Returns a token which can be used to suppress a given warning using
+ * <code>@SuppressWarnings</code> annotation, for a given problem ID
+ * ({@link IProblem }). If a particular problem is not suppressable,
+ * <code>null</code> will be returned.
+ *
+ * Note: <code>@SuppressWarnings</code> can only suppress warnings,
+ * which means that if some problems got promoted to ERROR using custom compiler
+ * settings ({@link IJavaProject#setOption(String, String)}), the
+ * <code>@SuppressWarnings</code> annotation will be ineffective.
+ *
+ * Note: <code>@SuppressWarnings</code> can be argumented with
+ * <code>"all"</code> so as to suppress all possible warnings at once.
+ *
+ * Note: The tokens returned are not necessarily standardized across Java
+ * compilers. If you were to use one of these tokens in an @SuppressWarnings
+ * annotation in the Java source code, the effects (if any) may vary from
+ * compiler to compiler.
+ *
+ * @param problemID
+ * the ID of a given warning to suppress
+ * @return a String which can be used in <code>@SuppressWarnings</code> annotation,
+ * or <code>null</code> if unable to suppress this warning.
+ * @since 3.1
+ */
+public static String getWarningToken(int problemID)
+</pre>
+</li>
+<li>More warning tokens are now recognized by <code>@SuppressWarnings</code>, see list below. Note that
+these are subject to changing in the near future.
+ <ul>
+ <li>all : any warning</li>
+ <li>boxing : autoboxing conversion</li>
+ <li>charConcat : char[] in String concat</li>
+ <li>conditionAssign : possible accidental boolean assignment</li>
+ <li>constructorName : method with constructor name</li>
+ <li>dep-ann : missing @Deprecated annotation</li>
+ <li>deprecation : deprecation outside deprecated code</li>
+ <li>emptyBlock : undocumented empty block</li>
+ <li>enumSwitch : incomplete enum switch</li>
+ <li>fieldHiding : field hiding another variable</li>
+ <li>finalBound : type parameter with final bound</li>
+ <li>finally : finally block not completing normally</li>
+ <li>indirectStatic : indirect reference to static member</li>
+ <li>intfAnnotation : annotation type used as super interface</li>
+ <li>intfNonInherited : interface non-inherited method compatibility</li>
+ <li>javadoc : invalid javadoc</li>
+ <li>localHiding : local variable hiding another variable</li>
+ <li>maskedCatchBlock : hidden catch block</li>
+ <li>nls : string literal lacking non-nls tag //$NON-NLS-<n>$</li>
+ <li>noEffectAssign : assignment without effect</li>
+ <li>over-ann : missing @Override annotation</li>
+ <li>pkgDefaultMethod : attempt to override package-default method</li>
+ <li>semicolon : unnecessary semicolon, empty statement</li>
+ <li>serial : missing serialVersionUID</li>
+ <li>unqualifiedField : unqualified reference to field</li>
+ <li>unchecked : unchecked type operation</li>
+ <li>unusedArgument : unread method parameter</li>
+ <li>unusedImport : unused import declaration</li>
+ <li>unusedLocal : unread local variable</li>
+ <li>unusedPrivate : unused private member declaration</li>
+ <li>unusedThrown : unused declared thrown exception</li>
+ <li>unnecessaryElse : unnecessary else clause</li>
+ <li>uselessTypeCheck : unnecessary cast/instanceof operation</li>
+ <li>specialParamHiding : constructor or setter parameter hiding another field</li>
+ <li>staticReceiver : non-static reference to static member</li>
+ <li>syntheticAccess : synthetic access for innerclass</li>
+ <li>typeHiding : type parameter hiding another type</li>
+ <li>varargsCast : varargs argument need explicit cast</li>
+ <li>warningToken : unhandled warning token</li>
+ </ul>
+</li>
+<li>
+SearchMatch now has a implicit field which shows whether the associated element is implicit or not
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94062">94062</a>).<br>
+Added new API methods to access this field:
+<ul>
+<li><code>SearchMatch#isImplicit()</code><br></li>
+<li><code>SearchMatch#setImplicit(boolean)</code></li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94053">94053</a>
+[javadoc] Unknown references are not warned for string or href in @see/@link tags
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94111">94111</a>
+[assist] provide parameter hints for template instantiations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=94062">94062</a>
+[1.5][search][annot] search for annotation elements incorrect match range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93392">93392</a>
+[1.5][search] Reference to implicit annotation element "value" has wrong offset
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84968">84968</a>
+[1.5][generics] Exception type handling broken in latest milestone
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75885">75885</a>
+[1.5][compiler] Naming convention for local innerclasses
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89426">89426</a>
+provide Java class file content type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93826">93826</a>
+ArrayIndexOutOfBoundsException when opening type hierarchy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83739">83739</a>
+[1.5] support @SuppressWarnings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89850">89850</a>
+Duplicate strings of VM path
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83750">83750</a>
+[perf] Excessive File.isFile calls for clients of JavaModel.getTarget(...)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92210">92210</a>
+[search] Search for method declaration in working set (source folder) searches in whole project
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93913">93913</a>
+wrong resolved type caused by a static import
+
+
+<a name="v_554"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M7 - 6th May 2005
+<br>Project org.eclipse.jdt.core v_554
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_554">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Code Assist doesn't propose anymore type completion when completion token is empty.<br>
+Note: the code to propose completion when token is empty is not removed.
+Change the value of Completion.NO_TYPE_COMPLETION_ON_EMPTY_TOKEN to re-enabled this behavior.
+</li>
+<li>@SuppressWarnings is now supported. Recognized warning names are: <code>"all"</code>, <code>"deprecation"</code>,
+<code>"serial"</code>, <code>"unchecked"</code>, <code>"finally"</code>.
+</li>
+<li>Changed Code Assist options.<br>
+ CODEASSIST_FORBIDDEN_REFERENCE_CHECK and CODEASSIST_DISCOURAGED_REFERENCE_CHECK are replaced by CODEASSIST_HIDE_RESTRICTED_REFERENCES.<br>
+ <pre>
+/*
+ * CODEASSIST / Hide Proposals for Restricted Completions
+ * When value is "never", never hide proposals for restricted completions.
+ * When value is "error", hide proposals for restricted completions if insertion of these completions would create a compile error.
+ * When value is "warning", hide proposals for restricted completions if insertion of these completions would create a compile error or warning.
+ * To configure the severity of restrictions, "org.eclipse.jdt.core.compiler.problem.forbiddenReference"
+ * option must be used for forbidden reference and "org.eclipse.jdt.core.compiler.problem.discouragedReference"
+ * option must be used for discouraged reference.
+ * - option id: "org.eclipse.jdt.core.codeComplete.restrictionsCheck"
+ * - possible values: { "never", "error", "warning" }
+ * - default: "error"
+ */
+ public static final String CODEASSIST_HIDE_RESTRICTED_REFERENCES;
+ </pre></li>
+<li>Removed 3.1 APIs <code>BindingKey#getDeclaringTypeSignature()</code> and
+ <code>BindingKey#toSignature()</code> as they were found error prone. See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93105">bug 93105</a>
+ for details.</li>
+<li>Added support for 'capture' inside Code Assist. Delaring type of a completion proposal is captured for qualified completion.</li>
+<li>Added APIs to replace a range of moved nodes (<code>ListRewrite#createMoveTarget(first, last, replacingNode, editGroup)</code>).
+ See <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91938">bug 91938</a> for details.
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93854">93854</a>
+IAE in Util.scanTypeSignature when scanning a signature retrieved from a binding key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93662">93662</a>
+Singature#getTypeParameters returns strange signature string
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93113">93113</a>
+Opening the Type Hierarchy of Object uses 400M of heap
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92071">92071</a>
+Duplicate entry on classpath with -promiscuous mode
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93486">93486</a>
+[compiler] Wrong compile errors reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93487">93487</a>
+IType#findMethods fails on vararg methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90186">90186</a>
+resolved key of methods should contain parametrized types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88082">88082</a>
+ASTParser#createASTs(..) does not use the given progress monitor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90612">90612</a>
+Forbidden types must not be available in Code Assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93105">93105</a>
+Remove unnecessary APIs on BindingKey
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93396">93396</a>
+[1.5] problem with recovery and enum constant body
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92899">92899</a>
+Empty extra attributes list should not appear in .classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93275">93275</a>
+Need ITypeBinding#getDeclaringClass() for capture types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93298">93298</a>
+[1.5][compiler] nested statics and templates compilation error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92477">92477</a>
+[1.5][compiler] Internal compiler error: NullPointerException in ReferenceBinding.findSuperTypeErasingTo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83083">83083</a>
+[1.5][compiler] NPE while checking bounds of type variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93204">93204</a>
+[1.5][compiler] EnumSet.of within generic class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90775">90775</a>
+[1.5][compiler] Missing unchecked warning
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88202">88202</a>
+Javadoc: clarify ITypeBinding#getTypeBounds()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93093">93093</a>
+[1.5][dom] Capture binding "? extends Number[]" has bound Object instead of Number[]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93102">93102</a>
+[1.5] Cannot restore capture binding from binding key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=93082">93082</a>
+[1.5][compiler] Eclipse accepts assignment between captures with array-type bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91467">91467</a>
+[1.5][compiler] Eclipse asks for and then complains about unnecessary cast
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92982">92982</a>
+[1.5][compiler] Bounds and erasure of capture and type variable bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84690">84690</a>
+[assist] CompletionProposal.getDeclarationSignature returns null for array types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92821">92821</a>
+[javadoc] Organize Imports - M6 - incorrectly retains import when only referered to in javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91542">91542</a>
+[1.5][search] JavaModelException on ResolvedSourceMethod during refactoring
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92981">92981</a>
+Content Assist overrides wrong method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91619">91619</a>
+Extraneous exported package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92872">92872</a>
+[api] API constants renamed in IProblem
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92888">92888</a>
+ITypeBinding#isEqualTo(..) is wrong for capture bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84224">84224</a>
+Need advice for finding duplicate Types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92944">92944</a>
+[1.5][search] SearchEngine#searchAllTypeNames doesn't honor enum or annotation element kind
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91078">91078</a>
+[search] Java search for package reference wrongly identifies inner class as package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92005">92005</a>
+AIOBE during content assist
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=67139">67139</a>
+[classpath] n^2 classpath computations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80063">80063</a>
+code assist allows overriding super class' private method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82208">82208</a>
+[search] BasicSearchEngine#searchAllTypeNames doc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=3336">3336</a>
+SearchEngine doesn't support CLASS and INTERFACE (1GIEPRK)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90160">90160</a>
+[search] SearchEngine.createJavaSearchScope swallows problems
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88174">88174</a>
+[1.5][search][enum] method declarations not found in anonymous enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91938">91938</a>
+[ast rewrite] new API: move range of nodes and replace
+
+<a name="v_553"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes <br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M7 - 26th April 2005
+<br>Project org.eclipse.jdt.core v_553
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_553">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Removed the need to load <code>java.lang.RuntimeException</code> and <code>java.lang.Error</code> eagerly
+during compilation when assessing unchecked exception diagnosis. This allows Java class library developpers to be
+more minimalistic.
+</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83230">bug 83230</a> required the index version to be incremented.
+ Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>Added support for Javadoc in package-info.java. Compiler now verifies package comment tags
+syntax and references for this compilation unit. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83804">83804</a> for
+further details.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91761">91761</a>
+[1.5][compiler] Return statements ignored in anonymous inner classes used as enum constant constructor parameters.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84049">84049</a>
+[javadoc][dom] Extended ranges wrong for method name without return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82673">82673</a>
+[search] Refactor->Rename on local class also renames references to different local classes with same name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81062">81062</a>
+[builder] Build is aborted even when no errors are occuring (incomplete build path == warning)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83012">83012</a>
+[1.5][search][annot] Search for annotations misses references in default and values constructs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92588">92588</a>
+Full build in reaction to beginRule failure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92451">92451</a>
+code assist failure: new+cast+arrays
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92373">92373</a>
+[1.5] Can't distinguish capture ITypeBindings by #getKey() or #isEqualTo()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92370">92370</a>
+[1.5] IAE in Signature.getParameterCount(..) for method proposal on capture type receiver
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92361">92361</a>
+[1.5] NPE in ITypeBinding#getJavaElement() for capture binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92315">92315</a>
+[search] NPE in MethodLocator.matchReportReference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86380">86380</a>
+[1.5][search][annot] Add support to find references inside annotations on a package declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83804">83804</a>
+[1.5][javadoc] Missing Javadoc node for package declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83501">83501</a>
+IBinding#getJavaElement needs better specification
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83230">83230</a>
+[1.5][search][annot] search for annotation elements does not seem to be implemented yet
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89624">89624</a>
+Open on selection proposes twice the same entry
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92237">92237</a>
+IType resolved key: key.toSignature has wrong format
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91804">91804</a>
+JavaProject.isOnClasspath(IJavaElement) should avoid resolving classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92059">92059</a>
IVariableBinding#getJavaElement() thows NPE for array's 'length' field
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84551">84551</a>
[1.5][compiler] compiler must not allow implicit static reference to outer type
@@ -65,11 +1444,11 @@
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89274">89274</a>
[1.5][compiler] Enums in hierarchies with generics produces unnecessary warnings and errors
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90137">90137</a>
-[1.5][compiler] Collections.sort (List<Comparable>) compile error
+[1.5][compiler] Collections.sort (List<Comparable>) compile error
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90879">90879</a>
[1.5][compiler] Cannot sort a raw Comparable
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85281">85281</a>
-[1.5][compiler] A<++Element> should not be assignable a A<+Element>
+[1.5][compiler] A<++Element> should not be assignable a A<+Element>
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91091">91091</a>
[quick assist] Cannot rename type name in file
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90881">90881</a>
@@ -991,8 +2370,6 @@
[DOM] AbortCompilation should not abort the creation of the tree
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86463">86463</a>
[1.5][compiler] Compiler-Bug using generics
-<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85815">85815</a>
-[1.5] warn when raw iterator is used
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86611">86611</a>
[1.4] 1.5 power double causes compiler internal failure
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86531">86531</a>
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index b6fb7f7..0e2892b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -19,6 +19,7 @@
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
@@ -68,6 +69,10 @@
public static boolean DEBUG = false;
public static boolean PERF = false;
+ // temporary constants to quickly disabled polish features if necessary
+ public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = true;
+ public final static boolean PROPOSE_MEMBER_TYPES = true;
+
private final static char[] ERROR_PATTERN = "*error*".toCharArray(); //$NON-NLS-1$
private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray(); //$NON-NLS-1$
private final static char[] SEMICOLON = new char[] { ';' };
@@ -77,6 +82,8 @@
private final static char[] INT = "int".toCharArray(); //$NON-NLS-1$
private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
private final static char[] VALUE = "value".toCharArray(); //$NON-NLS-1$
+ private final static char[] EXTENDS = "extends".toCharArray(); //$NON-NLS-1$
+ private final static char[] SUPER = "super".toCharArray(); //$NON-NLS-1$
private final static int SUPERTYPE = 1;
private final static int SUBTYPE = 2;
@@ -98,6 +105,7 @@
boolean assistNodeIsException;
boolean assistNodeIsInterface;
boolean assistNodeIsAnnotation;
+ boolean assistNodeIsConstructor;
IJavaProject javaProject;
CompletionParser parser;
@@ -107,9 +115,11 @@
char[] completionToken;
char[] qualifiedCompletionToken;
boolean resolvingImports = false;
+ boolean resolvingStaticImports = false;
boolean insideQualifiedReference = false;
boolean noProposal = true;
IProblem problem = null;
+ char[] fileName = null;
int startPosition, actualCompletionPosition, endPosition, offset;
HashtableOfObject knownPkgs = new HashtableOfObject(10);
HashtableOfObject knownTypes = new HashtableOfObject(10);
@@ -168,6 +178,44 @@
public int sourceStart() { return 0; }
public int sourceEnd() { return 0; }
};
+
+ private class AcceptedType {
+ public AcceptedType(
+ char[] packageName,
+ char[] simpleTypeName,
+ char[][] enclosingTypeNames,
+ int modifiers,
+ int accessibility) {
+ this.packageName = packageName;
+ this.simpleTypeName = simpleTypeName;
+ this.enclosingTypeNames = enclosingTypeNames;
+ this.modifiers = modifiers;
+ this.accessibility = accessibility;
+ }
+ public char[] packageName;
+ public char[] simpleTypeName;
+ public char[][] enclosingTypeNames;
+ public int modifiers;
+ public int accessibility;
+
+ public boolean mustBeQualified = false;
+ public char[] fullyQualifiedName = null;
+ public char[] qualifiedTypeName = null;
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ buffer.append(packageName);
+ buffer.append(',');
+ buffer.append(simpleTypeName);
+ buffer.append(',');
+ buffer.append(CharOperation.concatWith(enclosingTypeNames, '.'));
+ buffer.append('}');
+ return buffer.toString();
+ }
+ }
+
+ private ObjectVector acceptedTypes;
/**
* The CompletionEngine is responsible for computing source completions.
@@ -222,11 +270,11 @@
start,
end,
lineNumber);
- // TODO (david) problems could be detected in other units which got requested (see CompilationUnitProblemFinder)
if(CompletionEngine.this.actualCompletionPosition > start
&& this.lastErrorStart < start
&& pb.isError()
- && (pb.getID() & IProblem.Syntax) == 0) {
+ && (pb.getID() & IProblem.Syntax) == 0
+ && (CompletionEngine.this.fileName == null || CharOperation.equals(CompletionEngine.this.fileName, originatingFileName))) {
CompletionEngine.this.problem = pb;
this.lastErrorStart = start;
@@ -261,69 +309,270 @@
*/
public void acceptType(
char[] packageName,
- char[] typeName,
+ char[] simpleTypeName,
+ char[][] enclosingTypeNames,
int modifiers,
AccessRestriction accessRestriction) {
- char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
- char[] completionName = fullyQualifiedName;
-
- if (this.knownTypes.containsKey(completionName)) return;
-
- this.knownTypes.put(completionName, this);
-
+ if (this.options.checkVisibility) {
+ if((modifiers & IConstants.AccPublic) == 0) {
+ if((modifiers & IConstants.AccPrivate) != 0) return;
+
+ char[] currentPackage = CharOperation.concatWith(this.unitScope.fPackage.compoundName, '.');
+ if(!CharOperation.equals(packageName, currentPackage)) return;
+ }
+ }
+
int accessibility = IAccessRule.K_ACCESSIBLE;
if(accessRestriction != null) {
switch (accessRestriction.getProblemId()) {
case IProblem.ForbiddenReference:
- if(this.options.checkForbiddenReference) return;
+ if (this.options.checkForbiddenReference) {
+ return;
+ }
accessibility = IAccessRule.K_NON_ACCESSIBLE;
break;
case IProblem.DiscouragedReference:
- if(this.options.checkDiscouragedReference) return;
+ if (this.options.checkDiscouragedReference) {
+ return;
+ }
accessibility = IAccessRule.K_DISCOURAGED;
break;
}
}
- boolean isQualified = true;
+ if(acceptedTypes == null) {
+ acceptedTypes = new ObjectVector();
+ }
+ acceptedTypes.add(new AcceptedType(packageName, simpleTypeName, enclosingTypeNames, modifiers, accessibility));
+ }
+
+ private void acceptTypes() {
+ if(this.acceptedTypes == null) return;
+
+ int length = this.acceptedTypes.size();
+
+ if(length == 0) return;
+
+ HashtableOfObject onDemandFound = new HashtableOfObject();
+
+ next : for (int i = 0; i < length; i++) {
+ AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
+ char[] packageName = acceptedType.packageName;
+ char[] simpleTypeName = acceptedType.simpleTypeName;
+ char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
+ int modifiers = acceptedType.modifiers;
+ int accessibility = acceptedType.accessibility;
+
+ char[] typeName;
+ char[] flatEnclosingTypeNames;
+ if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
+ flatEnclosingTypeNames = null;
+ typeName = simpleTypeName;
+ } else {
+ flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
+ typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
+ }
+ char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
+
+ if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
+
+ this.knownTypes.put(fullyQualifiedName, this);
+
+ if (this.resolvingImports) {
+ char[] completionName;
+
+ if(this.resolvingStaticImports) {
+ if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
+ completionName = CharOperation.concat(fullyQualifiedName, new char[] { '.' });
+ } else if ((modifiers & IConstants.AccStatic) == 0) {
+ continue next;
+ } else {
+ completionName = CharOperation.concat(fullyQualifiedName, new char[] { ';' });
+ }
+ } else {
+ completionName = CharOperation.concat(fullyQualifiedName, new char[] { ';' });
+ }
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(accessibility);
+ if(insideQualifiedReference) {
+ relevance += computeRelevanceForCaseMatching(this.completionToken, fullyQualifiedName);
+ } else {
+ relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
+ }
+
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(completionName);
+ proposal.setFlags(modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setRelevance(relevance);
+ proposal.setAccessibility(accessibility);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ if(!this.importCachesInitialized) {
+ this.initializeImportCaches();
+ }
+
+ found : for (int j = 0; j < this.importCacheCount; j++) {
+ char[][] importName = this.importsCache[j];
+ if(CharOperation.equals(typeName, importName[0])) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ modifiers,
+ accessibility,
+ typeName,
+ fullyQualifiedName,
+ !CharOperation.equals(fullyQualifiedName, importName[1]));
+ continue next;
+ }
+ }
+
+
+ if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ modifiers,
+ accessibility,
+ typeName,
+ fullyQualifiedName,
+ false);
+ continue next;
+ } else {
+ char[] fullyQualifiedEnclosingTypeOrPackageName = null;
+
+ AcceptedType foundType = null;
+ if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
+ for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+ ImportBinding importBinding = this.onDemandImportsCache[j];
+
+ char[][] importName = importBinding.compoundName;
+ char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+ if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+ if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
+ fullyQualifiedEnclosingTypeOrPackageName =
+ CharOperation.concat(
+ packageName,
+ flatEnclosingTypeNames,
+ '.');
+ } else {
+ fullyQualifiedEnclosingTypeOrPackageName =
+ packageName;
+ }
+ }
+ if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ if((modifiers & IConstants.AccStatic) != 0) {
+ acceptedType.qualifiedTypeName = typeName;
+ acceptedType.fullyQualifiedName = fullyQualifiedName;
+ onDemandFound.put(
+ simpleTypeName,
+ acceptedType);
+ continue next;
+ }
+ } else {
+ acceptedType.qualifiedTypeName = typeName;
+ acceptedType.fullyQualifiedName = fullyQualifiedName;
+ onDemandFound.put(
+ simpleTypeName,
+ acceptedType);
+ continue next;
+ }
+ }
+ }
+ } else {
+ foundType.mustBeQualified = true;
+ }
+ proposeType(
+ packageName,
+ simpleTypeName,
+ modifiers,
+ accessibility,
+ typeName,
+ fullyQualifiedName,
+ true);
+ }
+ }
+ }
+ char[][] keys = onDemandFound.keyTable;
+ Object[] values = onDemandFound.valueTable;
+ int max = keys.length;
+ for (int i = 0; i < max; i++) {
+ if(keys[i] != null) {
+ AcceptedType value = (AcceptedType) values[i];
+ if(value != null) {
+ proposeType(
+ value.packageName,
+ value.simpleTypeName,
+ value.modifiers,
+ value.accessibility,
+ value.qualifiedTypeName,
+ value.fullyQualifiedName,
+ value.mustBeQualified);
+ }
+ }
+ }
+ this.acceptedTypes = null; // reset
+ }
+
+ private void proposeType(char[] packageName, char[] simpleTypeName, int modifiers, int accessibility, char[] typeName, char[] fullyQualifiedName, boolean isQualified) {
+ if(PROPOSE_MEMBER_TYPES) {
+ if(this.assistNodeIsClass) {
+ if((modifiers & (IConstants.AccInterface | IConstants.AccAnnotation | IConstants.AccEnum)) != 0 ) return;
+ } else if(this.assistNodeIsInterface) {
+ if((modifiers & (IConstants.AccInterface | IConstants.AccAnnotation)) == 0) return;
+ } else if (this.assistNodeIsAnnotation) {
+ if((modifiers & IConstants.AccAnnotation) == 0) return;
+ }
+ }
+
+ char[] completionName = fullyQualifiedName;
+ if(isQualified) {
+ if (packageName == null || packageName.length == 0)
+ if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+ return; // ignore types from the default package from outside it
+ } else {
+ completionName = simpleTypeName;
+ }
+
int relevance = computeBaseRelevance();
relevance += computeRelevanceForInterestingProposal();
relevance += computeRelevanceForRestrictions(accessibility);
- if (this.resolvingImports) {
- completionName = CharOperation.concat(completionName, new char[] { ';' });
- relevance += computeRelevanceForCaseMatching(this.completionToken, fullyQualifiedName);
- } else {
- if (mustQualifyType(packageName, typeName)) {
- if (packageName == null || packageName.length == 0)
- if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
- return; // ignore types from the default package from outside it
- } else {
- completionName = typeName;
- isQualified = false;
- }
- relevance += computeRelevanceForCaseMatching(this.completionToken, typeName);
- relevance += computeRelevanceForExpectingType(packageName, typeName);
- relevance += computeRelevanceForQualification(isQualified);
-
- int kind = modifiers & (IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation);
- switch (kind) {
- case IConstants.AccAnnotation:
- case IConstants.AccAnnotation | IConstants.AccInterface:
- relevance += computeRelevanceForAnnotation();
- relevance += computeRelevanceForInterface();
- break;
- case IConstants.AccEnum:
- relevance += computeRelevanceForEnum();
- break;
- case IConstants.AccInterface:
- relevance += computeRelevanceForInterface();
- break;
- default:
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForException(typeName);
- break;
- }
+ relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
+ relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
+ relevance += computeRelevanceForQualification(isQualified);
+
+ int kind = modifiers & (IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation);
+ switch (kind) {
+ case IConstants.AccAnnotation:
+ case IConstants.AccAnnotation | IConstants.AccInterface:
+ relevance += computeRelevanceForAnnotation();
+ relevance += computeRelevanceForInterface();
+ break;
+ case IConstants.AccEnum:
+ relevance += computeRelevanceForEnum();
+ break;
+ case IConstants.AccInterface:
+ relevance += computeRelevanceForInterface();
+ break;
+ default:
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException(simpleTypeName);
+ break;
}
this.noProposal = false;
@@ -361,7 +610,9 @@
int relevance = computeBaseRelevance();
relevance += computeRelevanceForInterestingProposal();
relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
- relevance += computeRelevanceForQualification(true);
+ if(!this.resolvingImports) {
+ relevance += computeRelevanceForQualification(true);
+ }
relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
this.noProposal = false;
@@ -401,14 +652,14 @@
this.requestor.acceptContext(context);
}
- private void complete(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope, boolean insideTypeAnnotation) {
+ private boolean complete(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope, boolean insideTypeAnnotation) {
setSourceRange(astNode.sourceStart, astNode.sourceEnd);
scope = computeForbiddenBindings(astNode, astNodeParent, scope);
computeUninterestingBindings(astNodeParent, scope);
if(astNodeParent != null) {
- if(!isValidParent(astNodeParent, astNode, scope)) return;
+ if(!isValidParent(astNodeParent, astNode, scope)) return false;
computeExpectedTypes(astNodeParent, astNode, scope);
}
@@ -464,6 +715,7 @@
&& switchStatement.expression.resolvedType != null
&& switchStatement.expression.resolvedType.isEnum()) {
if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ this.assistNodeIsEnum = true;
this.findEnumConstant(this.completionToken, (SwitchStatement) astNodeParent);
}
} else {
@@ -481,7 +733,7 @@
findTypesAndPackages(this.completionToken, scope);
if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
if(this.completionToken != null && this.completionToken.length != 0) {
- findKeywords(this.completionToken, singleNameReference.possibleKeywords);
+ findKeywords(this.completionToken, singleNameReference.possibleKeywords, false);
} else {
findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
}
@@ -504,23 +756,35 @@
this.completionToken = ((CompletionOnSingleTypeReference) astNode).token;
this.assistNodeIsClass = astNode instanceof CompletionOnClassReference;
- this.assistNodeIsEnum = this.assistNodeIsClass;
this.assistNodeIsException = astNode instanceof CompletionOnExceptionReference;
this.assistNodeIsInterface = astNode instanceof CompletionOnInterfaceReference;
-
+ this.assistNodeIsConstructor = ((CompletionOnSingleTypeReference) astNode).isConstructorType;
+
// can be the start of a qualified type name
if (qualifiedBinding == null) {
- findTypesAndPackages(this.completionToken, scope);
- } else {
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- findMemberTypes(
- this.completionToken,
- (ReferenceBinding) qualifiedBinding,
- scope,
- scope.enclosingSourceType(),
- false,
- new ObjectVector());
- }
+ if(this.completionToken.length == 0 &&
+ (astNodeParent instanceof ParameterizedSingleTypeReference ||
+ astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
+ this.setSourceRange(astNode.sourceStart, astNode.sourceStart - 1, false);
+
+ findParameterizedType((TypeReference)astNodeParent);
+ } else {
+ findTypesAndPackages(this.completionToken, scope);
+ }
+ } else {
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ false,
+ !this.assistNodeIsConstructor,
+ null,
+ new ObjectVector());
+ }
}
} else {
@@ -537,18 +801,25 @@
setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
if (receiverType != null) {
- findFieldsAndMethods(this.completionToken, receiverType, scope, ref, scope,false,false);
+ findFieldsAndMethods(this.completionToken, receiverType.capture(scope, ref.sourceEnd), scope, ref, scope,false,false);
}
} else {
- if (qualifiedBinding instanceof ReferenceBinding) {
+ if (qualifiedBinding instanceof ReferenceBinding &&
+ !(qualifiedBinding instanceof TypeVariableBinding)) {
boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- findMemberTypes(this.completionToken, receiverType, scope, scope.enclosingSourceType(), false, new ObjectVector());
+ findMemberTypes(
+ this.completionToken,
+ receiverType,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ new ObjectVector());
}
if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
findClassField(this.completionToken, (TypeBinding) qualifiedBinding, scope);
@@ -560,7 +831,7 @@
((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
if(this.completionToken.length > 0) {
- findKeywords(this.completionToken, new char[][]{Keywords.THIS});
+ findKeywords(this.completionToken, new char[][]{Keywords.THIS}, false);
} else {
int relevance = computeBaseRelevance();
relevance += computeRelevanceForInterestingProposal();
@@ -630,7 +901,6 @@
this.insideQualifiedReference = true;
this.assistNodeIsClass = astNode instanceof CompletionOnQualifiedClassReference;
- this.assistNodeIsEnum = this.assistNodeIsClass;
this.assistNodeIsException = astNode instanceof CompletionOnQualifiedExceptionReference;
this.assistNodeIsInterface = astNode instanceof CompletionOnQualifiedInterfaceReference;
@@ -640,7 +910,8 @@
long completionPosition = ref.sourcePositions[ref.tokens.length];
// get the source positions of the completion identifier
- if (qualifiedBinding instanceof ReferenceBinding) {
+ if (qualifiedBinding instanceof ReferenceBinding &&
+ !(qualifiedBinding instanceof TypeVariableBinding)) {
if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
findMemberTypes(
@@ -673,12 +944,12 @@
this.completionToken = access.token;
if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- findKeywords(this.completionToken, new char[][]{Keywords.NEW});
+ findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false);
}
findFieldsAndMethods(
this.completionToken,
- (TypeBinding) qualifiedBinding,
+ ((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
scope,
access,
scope,
@@ -703,7 +974,7 @@
findMethods(
this.completionToken,
argTypes,
- (ReferenceBinding) qualifiedBinding,
+ (ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
scope,
new ObjectVector(),
false,
@@ -837,7 +1108,7 @@
if(astNode instanceof CompletionOnKeyword) {
if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
- findKeywords(keyword.getToken(), keyword.getPossibleKeywords());
+ findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken());
}
} else if(astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
@@ -871,18 +1142,27 @@
findTypesAndPackages(this.completionToken, scope);
} else if(annot.type instanceof CompletionOnQualifiedTypeReference) {
+ this.insideQualifiedReference = true;
+
CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
this.completionToken = type.completionIdentifier;
long completionPosition = type.sourcePositions[type.tokens.length];
- setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
-
- findMemberTypes(
- this.completionToken,
- (ReferenceBinding) qualifiedBinding,
- scope,
- scope.enclosingSourceType(),
- false,
- new ObjectVector());
+ if (qualifiedBinding instanceof PackageBinding) {
+
+ setSourceRange(astNode.sourceStart, (int) completionPosition);
+ // replace to the end of the completion identifier
+ findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding);
+ } else {
+ setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ new ObjectVector());
+ }
}
} else if (astNode instanceof CompletionOnMemberValueName) {
if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
@@ -891,31 +1171,36 @@
this.completionToken = memberValuePair.name;
- MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
- this.findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), (ReferenceBinding)annotation.resolvedType);
- if(memberValuePairs == null || memberValuePairs.length == 0) {
- if(annotation.resolvedType instanceof ReferenceBinding) {
- MethodBinding[] methodBindings =
- ((ReferenceBinding)annotation.resolvedType).availableMethods();
- if(methodBindings != null &&
- methodBindings.length == 1 &&
- CharOperation.equals(methodBindings[0].selector, VALUE)) {
- if(this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
- findTypesAndPackages(this.completionToken, scope);
- } else {
- findVariablesAndMethods(
- this.completionToken,
- scope,
- FakeInvocationSite,
- scope,
- insideTypeAnnotation,
- true);
- // can be the start of a qualified type name
- findTypesAndPackages(this.completionToken, scope);
+ if(this.completionToken.length == 0) {
+ this.setSourceRange(astNode.sourceStart, astNode.sourceStart - 1, false);
+
+ findAnnotationReference(annotation.type);
+ } else {
+ MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
+ this.findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), (ReferenceBinding)annotation.resolvedType);
+ if(memberValuePairs == null || memberValuePairs.length == 0) {
+ if(annotation.resolvedType instanceof ReferenceBinding) {
+ MethodBinding[] methodBindings =
+ ((ReferenceBinding)annotation.resolvedType).availableMethods();
+ if(methodBindings != null &&
+ methodBindings.length == 1 &&
+ CharOperation.equals(methodBindings[0].selector, VALUE)) {
+ if(this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
+ findTypesAndPackages(this.completionToken, scope);
+ } else {
+ findVariablesAndMethods(
+ this.completionToken,
+ scope,
+ FakeInvocationSite,
+ scope,
+ insideTypeAnnotation,
+ true);
+ // can be the start of a qualified type name
+ findTypesAndPackages(this.completionToken, scope);
+ }
}
}
}
-
}
}
}
@@ -933,6 +1218,7 @@
}
}
}
+ return true;
}
public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
@@ -945,7 +1231,8 @@
topLevelType = topLevelType.getDeclaringType();
}
- CompilationResult compilationResult = new CompilationResult(topLevelType.getParent().getElementName().toCharArray(), 1, 1, this.compilerOptions.maxProblemsPerUnit);
+ this.fileName = topLevelType.getParent().getElementName().toCharArray();
+ CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
CompilationUnitDeclaration compilationUnit = null;
@@ -1003,9 +1290,8 @@
} catch (CompletionNodeFound e) {
// completionNodeFound = true;
if (e.astNode != null) {
- contextAccepted = true;
// if null then we found a problem in the completion node
- complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope, e.insideTypeAnnotation);
+ contextAccepted = complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope, e.insideTypeAnnotation);
}
}
}
@@ -1020,6 +1306,26 @@
}
}
}
+ } catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
} catch(JavaModelException e) {
// Do nothing
}
@@ -1095,6 +1401,7 @@
this.requestor.beginReporting();
boolean contextAccepted = false;
try {
+ this.fileName = sourceUnit.getFileName();
this.actualCompletionPosition = completionPosition - 1;
this.offset = pos;
// for now until we can change the UI.
@@ -1129,35 +1436,50 @@
for (int i = 0, length = imports.length; i < length; i++) {
ImportReference importReference = imports[i];
if (importReference instanceof CompletionOnImportReference) {
- contextAccepted = true;
- this.requestor.acceptContext(new CompletionContext());
- findImports((CompletionOnImportReference) importReference);
- if(this.noProposal && this.problem != null) {
- this.requestor.completionFailure(this.problem);
- if(DEBUG) {
- this.printDebug(this.problem);
- }
- }
- if(importReference.isStatic()) {
- this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
- if ((this.unitScope = parsedUnit.scope) != null) {
- char[][] oldTokens = importReference.tokens;
- int tokenCount = oldTokens.length;
+ this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+ if ((this.unitScope = parsedUnit.scope) != null) {
+ contextAccepted = true;
+ this.requestor.acceptContext(new CompletionContext());
+
+ setSourceRange(
+ importReference.sourceStart,
+ importReference.declarationSourceEnd);
+
+ char[][] oldTokens = importReference.tokens;
+ int tokenCount = oldTokens.length;
+ if (tokenCount == 1) {
+ findImports((CompletionOnImportReference)importReference, true);
+ } else if(tokenCount > 1){
+ this.insideQualifiedReference = true;
+
char[] lastToken = oldTokens[tokenCount - 1];
char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
- if(binding != null && binding instanceof ReferenceBinding) {
- ReferenceBinding ref = (ReferenceBinding) binding;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- this.findImportsOfMemberTypes(lastToken, ref);
+ if(binding != null) {
+ if(binding instanceof PackageBinding) {
+ findImports((CompletionOnImportReference)importReference, false);
+ } else {
+ ReferenceBinding ref = (ReferenceBinding) binding;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ this.findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
+ }
+ if(importReference.isStatic()) {
+ if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ this.findImportsOfStaticFields(lastToken, ref);
+ }
+ if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
+ this.findImportsOfStaticMethdods(lastToken, ref);
+ }
+ }
}
- if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
- this.findImportsOfStaticFields(lastToken, ref);
- }
- if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
- this.findImportsOfStaticMethdods(lastToken, ref);
- }
+ }
+ }
+
+ if(this.noProposal && this.problem != null) {
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
}
}
}
@@ -1168,7 +1490,7 @@
if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
setSourceRange(importReference.sourceStart, importReference.sourceEnd);
CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
- findKeywords(keyword.getToken(), keyword.getPossibleKeywords());
+ findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false);
}
if(this.noProposal && this.problem != null) {
this.requestor.completionFailure(this.problem);
@@ -1207,9 +1529,8 @@
System.out.println(this.parser.assistNodeParent);
}
}
- contextAccepted = true;
// if null then we found a problem in the completion node
- complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope, e.insideTypeAnnotation);
+ contextAccepted = complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope, e.insideTypeAnnotation);
}
}
}
@@ -1313,6 +1634,58 @@
}
}
}
+ private void findAnnotationReference(TypeReference ref) {
+ ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
+ if(refBinding != null) {
+ char[] packageName = refBinding.qualifiedPackageName();
+ char[] typeName = refBinding.qualifiedSourceName();
+
+ int accessibility = IAccessRule.K_ACCESSIBLE;
+ if(refBinding.hasRestrictedAccess()) {
+ AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(refBinding);
+ if(accessRestriction != null) {
+ switch (accessRestriction.getProblemId()) {
+ case IProblem.ForbiddenReference:
+ if (this.options.checkForbiddenReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_NON_ACCESSIBLE;
+ break;
+ case IProblem.DiscouragedReference:
+ if (this.options.checkDiscouragedReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_DISCOURAGED;
+ break;
+ }
+ }
+ }
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
+ relevance += computeRelevanceForExpectingType(refBinding);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
+
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(getSignature(refBinding));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(CharOperation.NO_CHAR);
+ proposal.setFlags(refBinding.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setRelevance(relevance);
+ proposal.setAccessibility(accessibility);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ }
private void findAnonymousType(
ReferenceBinding currentType,
TypeBinding[] argTypes,
@@ -1341,6 +1714,7 @@
CharOperation.NO_CHAR_CHAR,
CharOperation.NO_CHAR,
CharOperation.NO_CHAR));
+ //proposal.setOriginalSignature(null);
//proposal.setUniqueKey(null);
proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
@@ -1385,10 +1759,23 @@
if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
//proposal.setDeclarationSignature(null);
- proposal.setSignature(
- createNonGenericTypeSignature(
- CharOperation.concatWith(JAVA_LANG, '.'),
- CLASS));
+ char[] signature =
+ createNonGenericTypeSignature(
+ CharOperation.concatWith(JAVA_LANG, '.'),
+ CLASS);
+ if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
+ // add type argument
+ char[] typeArgument = getTypeSignature(receiverType);
+ int oldLength = signature.length;
+ int argumentLength = typeArgument.length;
+ int newLength = oldLength + argumentLength + 2;
+ System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1);
+ signature[oldLength - 1] = '<';
+ System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength);
+ signature[newLength - 2] = '>';
+ signature[newLength - 1] = ';';
+ }
+ proposal.setSignature(signature);
//proposal.setDeclarationPackageName(null);
//proposal.setDeclarationTypeName(null);
proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
@@ -1410,6 +1797,16 @@
if(expressionType != null && expressionType.isEnum()) {
ReferenceBinding enumType = (ReferenceBinding) expressionType;
+ CaseStatement[] cases = switchStatement.cases;
+
+ char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
+ int alreadyUsedConstantCount = 0;
+ for (int i = 0; i < switchStatement.caseCount; i++) {
+ if(cases[i].isEnumConstant) {
+ alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
+ }
+ }
+
FieldBinding[] fields = enumType.fields();
int enumConstantLength = enumConstantName.length;
@@ -1425,10 +1822,14 @@
if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)) continue next;
char[] completion = field.name;
+
+ for (int i = 0; i < alreadyUsedConstantCount; i++) {
+ if(CharOperation.equals(alreadyUsedConstants[i], completion)) continue next;
+ }
int relevance = computeBaseRelevance();
relevance += computeRelevanceForInterestingProposal(field);
- relevance += R_ENUM_CONSTANT;
+ relevance += computeRelevanceForEnum();
relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
relevance += computeRelevanceForExpectingType(field.type);
relevance += computeRelevanceForQualification(false);
@@ -1507,6 +1908,10 @@
CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
proposal.setDeclarationSignature(getSignature(currentType));
proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
proposal.setParameterPackageNames(parameterPackageNames);
@@ -1514,6 +1919,7 @@
//proposal.setPackageName(null);
//proposal.setTypeName(null);
proposal.setName(name);
+ proposal.setIsContructor(true);
proposal.setCompletion(completion);
proposal.setFlags(constructor.modifiers);
proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
@@ -1587,6 +1993,10 @@
proposal.setDeclarationSignature(getSignature(currentType));
proposal.setDeclarationKey(currentType.computeUniqueKey());
proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
proposal.setKey(constructor.computeUniqueKey());
proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
@@ -1614,6 +2024,10 @@
CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
proposal.setDeclarationSignature(getSignature(currentType));
proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
proposal.setParameterPackageNames(parameterPackageNames);
@@ -1621,6 +2035,7 @@
//proposal.setPackageName(null);
//proposal.setTypeName(null);
proposal.setName(currentType.sourceName());
+ proposal.setIsContructor(true);
proposal.setCompletion(completion);
proposal.setFlags(constructor.modifiers);
proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
@@ -1895,7 +2310,7 @@
this.noProposal = false;
if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
- //proposal.setDeclarationSignature(null);
+ proposal.setDeclarationSignature(getSignature(receiverType));
proposal.setSignature(INT_SIGNATURE);
//proposal.setDeclarationPackageName(null);
//proposal.setDeclarationTypeName(null);
@@ -1937,13 +2352,14 @@
this.noProposal = false;
if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
- //proposal.setDeclarationSignature(null);
+ proposal.setDeclarationSignature(getSignature(receiverType));
proposal.setSignature(
createMethodSignature(
CharOperation.NO_CHAR_CHAR,
CharOperation.NO_CHAR_CHAR,
CharOperation.concatWith(JAVA_LANG, '.'),
OBJECT));
+ //proposal.setOriginalSignature(null);
//proposal.setDeclarationPackageName(null);
//proposal.setDeclarationTypeName(null);
//proposal.setParameterPackageNames(null);
@@ -1998,7 +2414,7 @@
}
}
- private void findImports(CompletionOnImportReference importReference) {
+ private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
char[][] tokens = importReference.tokens;
char[] importName = CharOperation.concatWith(tokens, '.');
@@ -2011,9 +2427,7 @@
importName = CharOperation.concat(importName, new char[]{'.'});
this.resolvingImports = true;
- setSourceRange(
- importReference.sourceStart,
- importReference.declarationSourceEnd);
+ this.resolvingStaticImports = importReference.isStatic();
this.completionToken = importName;
// want to replace the existing .*;
@@ -2021,11 +2435,12 @@
this.nameEnvironment.findPackages(importName, this);
}
if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- this.nameEnvironment.findTypes(importName, this);
+ this.nameEnvironment.findTypes(importName, findMembers && PROPOSE_MEMBER_TYPES, this);
+ acceptTypes();
}
}
- private void findImportsOfMemberTypes(char[] typeName, ReferenceBinding ref) {
+ private void findImportsOfMemberTypes(char[] typeName, ReferenceBinding ref, boolean onlyStatic) {
ReferenceBinding[] memberTypes = ref.memberTypes();
int typeLength = typeName.length;
@@ -2034,6 +2449,9 @@
// if (!wantClasses && memberType.isClass()) continue next;
// if (!wantInterfaces && memberType.isInterface()) continue next;
+ if (onlyStatic && !memberType.isStatic())
+ continue next;
+
if (typeLength > memberType.sourceName.length)
continue next;
@@ -2224,11 +2642,11 @@
// what about onDemand types? Ignore them since it does not happen!
// import p1.p2.A.*;
- private void findKeywords(char[] keyword, char[][] choices) {
+ private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken) {
if(choices == null || choices.length == 0) return;
int length = keyword.length;
- if (length > 0)
+ if (canCompleteEmptyToken || length > 0)
for (int i = 0; i < choices.length; i++)
if (length <= choices[i].length
&& CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
@@ -2376,7 +2794,7 @@
}
System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
- findKeywords(token, keywords);
+ findKeywords(token, keywords, false);
}
// Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
@@ -2386,7 +2804,9 @@
ObjectVector typesFound,
ReferenceBinding receiverType,
SourceTypeBinding invocationType,
- boolean staticOnly) {
+ boolean staticOnly,
+ boolean fromStaticImport,
+ boolean checkQualification) {
// Inherited member types which are hidden by subclasses are filtered out
// No visibility checks can be performed without the scope & invocationSite
@@ -2441,11 +2861,47 @@
typesFound.add(memberType);
+ if(!this.insideQualifiedReference && PROPOSE_MEMBER_TYPES) {
+ if(this.assistNodeIsClass) {
+ if(!memberType.isClass()) continue next;
+ } else if(this.assistNodeIsInterface) {
+ if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!memberType.isAnnotationType()) continue next;
+ }
+ }
+
+ char[] completionName = memberType.sourceName();
+
+ boolean isQualified = false;
+ if(checkQualification && !fromStaticImport) {
+ char[] memberPackageName = memberType.qualifiedPackageName();
+ char[] memberTypeName = memberType.sourceName();
+ char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
+ if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
+ if (memberPackageName == null || memberPackageName.length == 0)
+ if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+ break next; // ignore types from the default package from outside it
+ isQualified = true;
+ completionName =
+ CharOperation.concat(
+ memberPackageName,
+ CharOperation.concat(
+ memberEnclosingTypeNames,
+ memberTypeName,
+ '.'),
+ '.');
+ }
+ }
+
int relevance = computeBaseRelevance();
relevance += computeRelevanceForInterestingProposal();
relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
relevance += computeRelevanceForExpectingType(memberType);
relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ if(!insideQualifiedReference) {
+ relevance += computeRelevanceForQualification(isQualified);
+ }
if (memberType.isClass()) {
relevance += computeRelevanceForClass();
@@ -2463,7 +2919,7 @@
proposal.setSignature(getSignature(memberType));
proposal.setPackageName(memberType.qualifiedPackageName());
proposal.setTypeName(memberType.qualifiedSourceName());
- proposal.setCompletion(memberType.sourceName());
+ proposal.setCompletion(completionName);
proposal.setFlags(memberType.modifiers);
proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
proposal.setRelevance(relevance);
@@ -2481,6 +2937,29 @@
Scope scope,
SourceTypeBinding typeInvocation,
boolean staticOnly,
+ ObjectVector typesFound) {
+ findMemberTypes(
+ typeName,
+ receiverType,
+ scope,
+ typeInvocation,
+ staticOnly,
+ false,
+ false,
+ false,
+ null,
+ typesFound);
+ }
+ private void findMemberTypes(
+ char[] typeName,
+ ReferenceBinding receiverType,
+ Scope scope,
+ SourceTypeBinding typeInvocation,
+ boolean staticOnly,
+ boolean fromStaticImport,
+ boolean checkQualification,
+ boolean proposeAllMemberTypes,
+ SourceTypeBinding typeToIgnore,
ObjectVector typesFound) {
ReferenceBinding currentType = receiverType;
@@ -2499,7 +2978,9 @@
typesFound,
receiverType,
typeInvocation,
- staticOnly);
+ staticOnly,
+ fromStaticImport,
+ checkQualification);
return;
}
@@ -2523,17 +3004,37 @@
lastPosition);
interfacesToVisit[lastPosition] = itsInterfaces;
}
-
+
findMemberTypes(
typeName,
currentType.memberTypes(),
typesFound,
receiverType,
typeInvocation,
- staticOnly);
+ staticOnly,
+ fromStaticImport,
+ checkQualification);
+
currentType = currentType.superclass();
} while (currentType != null);
+
+
+ if(proposeAllMemberTypes) {
+ ReferenceBinding[] memberTypes = receiverType.memberTypes();
+ for (int i = 0; i < memberTypes.length; i++) {
+ if(memberTypes[i] != typeToIgnore) {
+ findSubMemberTypes(
+ typeName,
+ memberTypes[i],
+ scope,
+ typeInvocation,
+ staticOnly,
+ fromStaticImport,
+ typesFound);
+ }
+ }
+ }
if (interfacesToVisit != null) {
for (int i = 0; i <= lastPosition; i++) {
@@ -2544,15 +3045,17 @@
if ((anInterface.tagBits & TagBits.InterfaceVisited) == 0) {
// if interface as not already been visited
anInterface.tagBits |= TagBits.InterfaceVisited;
-
+
findMemberTypes(
typeName,
anInterface.memberTypes(),
typesFound,
receiverType,
typeInvocation,
- staticOnly);
-
+ staticOnly,
+ fromStaticImport,
+ checkQualification);
+
ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
if (itsInterfaces != NoSuperInterfaces) {
@@ -2577,6 +3080,52 @@
}
}
}
+
+ private void findSubMemberTypes(
+ char[] typeName,
+ ReferenceBinding receiverType,
+ Scope scope,
+ SourceTypeBinding typeInvocation,
+ boolean staticOnly,
+ boolean fromStaticImport,
+ ObjectVector typesFound) {
+
+ ReferenceBinding currentType = receiverType;
+ if (typeName == null || typeName.length == 0)
+ return;
+
+ if (currentType.superInterfaces() == null)
+ return; // we're trying to find a supertype
+
+ findMemberTypes(
+ typeName,
+ currentType.memberTypes(),
+ typesFound,
+ receiverType,
+ typeInvocation,
+ staticOnly,
+ fromStaticImport,
+ true);
+
+ ReferenceBinding[] memberTypes = receiverType.memberTypes();
+ next : for (int i = 0; i < memberTypes.length; i++) {
+ if (this.options.checkVisibility) {
+ if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
+ continue next;
+ } else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
+ continue next;
+ }
+ }
+ findSubMemberTypes(
+ typeName,
+ memberTypes[i],
+ scope,
+ typeInvocation,
+ staticOnly,
+ fromStaticImport,
+ typesFound);
+ }
+ }
private void findIntefacesMethods(
char[] selector,
@@ -2889,6 +3438,10 @@
CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
proposal.setDeclarationSignature(getSignature(method.declaringClass));
proposal.setSignature(getSignature(method));
+ MethodBinding original = method.original();
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
proposal.setParameterPackageNames(parameterPackageNames);
@@ -2974,6 +3527,10 @@
CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
proposal.setDeclarationSignature(getSignature(method.declaringClass));
proposal.setSignature(getSignature(method));
+ MethodBinding original = method.original();
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
proposal.setParameterPackageNames(parameterPackageNames);
@@ -3070,17 +3627,18 @@
private int computeRelevanceForExpectingType(TypeBinding proposalType){
if(this.expectedTypes != null && proposalType != null) {
for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ int relevance = R_EXPECTED_TYPE;
if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
- return R_EXACT_EXPECTED_TYPE;
+ relevance = R_EXACT_EXPECTED_TYPE;
}
if((this.expectedTypesFilter & SUBTYPE) != 0
&& proposalType.isCompatibleWith(this.expectedTypes[i])) {
- return R_EXPECTED_TYPE;
+ return relevance;
}
if((this.expectedTypesFilter & SUPERTYPE) != 0
&& this.expectedTypes[i].isCompatibleWith(proposalType)) {
- return R_EXPECTED_TYPE;
+ return relevance;
}
}
}
@@ -3141,7 +3699,10 @@
if (method.isConstructor()) continue next;
- if (method.isFinal()) continue next;
+ if (method.isFinal()) {
+ newMethodsFound.add(method);
+ continue next;
+ }
// if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
if(method.isStatic()) {
@@ -3154,8 +3715,7 @@
if(onlyStaticMethods) continue next;
}
- if (this.options.checkVisibility
- && !method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;
+ if (!method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;
if (exactMatch) {
if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
@@ -3188,76 +3748,19 @@
int length = method.parameters.length;
char[][] parameterPackageNames = new char[length][];
- char[][] parameterTypeNames = new char[length][];
+ char[][] parameterFullTypeNames = new char[length][];
for (int i = 0; i < length; i++) {
TypeBinding type = method.parameters[i];
parameterPackageNames[i] = type.qualifiedPackageName();
- parameterTypeNames[i] = type.qualifiedSourceName();
+ parameterFullTypeNames[i] = type.qualifiedSourceName();
}
- char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
+ char[][] parameterNames = findMethodParameterNames(method, parameterFullTypeNames);
StringBuffer completion = new StringBuffer(10);
- // flush uninteresting modifiers
- int insertedModifiers = method.modifiers & ~(IConstants.AccNative | IConstants.AccAbstract);
-
if (!exactMatch) {
- if(insertedModifiers != CompilerModifiers.AccDefault){
- ASTNode.printModifiers(insertedModifiers, completion);
- }
- char[] returnPackageName = method.returnType.qualifiedPackageName();
- char[] returnTypeName = method.returnType.qualifiedSourceName();
- if(mustQualifyType(returnPackageName, returnTypeName)) {
- completion.append(CharOperation.concat(returnPackageName, returnTypeName,'.'));
- } else {
- completion.append(method.returnType.sourceName());
- }
- completion.append(' ');
- completion.append(method.selector);
- completion.append('(');
-
- for(int i = 0; i < length ; i++){
- if(mustQualifyType(parameterPackageNames[i], parameterTypeNames[i])){
- completion.append(CharOperation.concat(parameterPackageNames[i], parameterTypeNames[i], '.'));
- } else {
- completion.append(parameterTypeNames[i]);
- }
- completion.append(' ');
- if(parameterNames != null){
- completion.append(parameterNames[i]);
- } else {
- completion.append('%');
- }
- if(i != (length - 1))
- completion.append(',');
- }
- completion.append(')');
-
- ReferenceBinding[] exceptions = method.thrownExceptions;
-
- if (exceptions != null && exceptions.length > 0){
- completion.append(' ');
- completion.append(THROWS);
- completion.append(' ');
- for(int i = 0; i < exceptions.length ; i++){
- ReferenceBinding exception = exceptions[i];
-
- char[] exceptionPackageName = exception.qualifiedPackageName();
- char[] exceptionTypeName = exception.qualifiedSourceName();
-
- if(i != 0){
- completion.append(',');
- completion.append(' ');
- }
-
- if(mustQualifyType(exceptionPackageName, exceptionTypeName)){
- completion.append(CharOperation.concat(exceptionPackageName, exceptionTypeName, '.'));
- } else {
- completion.append(exception.sourceName());
- }
- }
- }
+ createMethod(method, parameterPackageNames, parameterFullTypeNames, parameterNames, completion);
}
int relevance = computeBaseRelevance();
@@ -3273,11 +3776,15 @@
proposal.setDeclarationSignature(getSignature(method.declaringClass));
proposal.setDeclarationKey(method.declaringClass.computeUniqueKey());
proposal.setSignature(getSignature(method));
+ MethodBinding original = method.original();
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
proposal.setKey(method.computeUniqueKey());
proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
+ proposal.setParameterTypeNames(parameterFullTypeNames);
proposal.setPackageName(method.returnType.qualifiedPackageName());
proposal.setTypeName(method.returnType.qualifiedSourceName());
proposal.setCompletion(completion.toString().toCharArray());
@@ -3294,6 +3801,170 @@
}
methodsFound.addAll(newMethodsFound);
}
+ private void createTypeVariable(TypeVariableBinding typeVariable, StringBuffer completion) {
+ completion.append(typeVariable.sourceName);
+
+ if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
+ completion.append(' ');
+ completion.append(EXTENDS);
+ completion.append(' ');
+ createType(typeVariable.superclass, completion);
+ }
+ if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != NoSuperInterfaces) {
+ if (typeVariable.firstBound != typeVariable.superclass) {
+ completion.append(' ');
+ completion.append(EXTENDS);
+ completion.append(' ');
+ }
+ for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
+ if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
+ completion.append(' ');
+ completion.append(EXTENDS);
+ completion.append(' ');
+ }
+ createType(typeVariable.superInterfaces[i], completion);
+ }
+ }
+ }
+
+ private void createType(TypeBinding type, StringBuffer completion) {
+ if (type.isBaseType()) {
+ completion.append(type.sourceName());
+ } else if (type.isTypeVariable()) {
+ completion.append(type.sourceName());
+ } else if (type.isWildcard()) {
+ WildcardBinding wildcardBinding = (WildcardBinding) type;
+ completion.append('?');
+ switch (wildcardBinding.boundKind) {
+ case Wildcard.EXTENDS:
+ completion.append(' ');
+ completion.append(EXTENDS);
+ completion.append(' ');
+ createType(wildcardBinding.bound, completion);
+ if(wildcardBinding.otherBounds != null) {
+
+ int length = wildcardBinding.otherBounds.length;
+ for (int i = 0; i < length; i++) {
+ completion.append(' ');
+ completion.append('&');
+ completion.append(' ');
+ createType(wildcardBinding.otherBounds[i], completion);
+ }
+ }
+ break;
+ case Wildcard.SUPER:
+ completion.append(' ');
+ completion.append(SUPER);
+ completion.append(' ');
+ createType(wildcardBinding.bound, completion);
+ break;
+ }
+ } else if (type.isArrayType()) {
+ createType(type.leafComponentType(), completion);
+ int dim = type.dimensions();
+ for (int i = 0; i < dim; i++) {
+ completion.append('[');
+ completion.append(']');
+ }
+ } else if (type.isParameterizedType()) {
+ ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
+ if (type.isMemberType()) {
+ createType(parameterizedType.enclosingType(), completion);
+ completion.append('.');
+ completion.append(parameterizedType.sourceName);
+ } else {
+ completion.append(CharOperation.concatWith(parameterizedType.type.compoundName, '.'));
+ }
+ if (parameterizedType.arguments != null) {
+ completion.append('<');
+ for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
+ if (i != 0) completion.append(',');
+ createType(parameterizedType.arguments[i], completion);
+ }
+ completion.append('>');
+ }
+ } else {
+ char[] packageName = type.qualifiedPackageName();
+ char[] typeName = type.qualifiedSourceName();
+ if(mustQualifyType(
+ packageName,
+ type.sourceName(),
+ type.isMemberType() ? type.enclosingType().qualifiedSourceName() : null,
+ ((ReferenceBinding)type).modifiers)) {
+ completion.append(CharOperation.concat(packageName, typeName,'.'));
+ } else {
+ completion.append(type.sourceName());
+ }
+ }
+ }
+ private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, StringBuffer completion) {
+ //// Modifiers
+ // flush uninteresting modifiers
+ int insertedModifiers = method.modifiers & ~(IConstants.AccNative | IConstants.AccAbstract);
+ if(insertedModifiers != CompilerModifiers.AccDefault){
+ ASTNode.printModifiers(insertedModifiers, completion);
+ }
+
+ //// Type parameters
+
+ TypeVariableBinding[] typeVariableBindings = method.typeVariables;
+ if(typeVariableBindings != null && typeVariableBindings.length != 0) {
+ completion.append('<');
+ for (int i = 0; i < typeVariableBindings.length; i++) {
+ if(i != 0) {
+ completion.append(',');
+ completion.append(' ');
+ }
+ createTypeVariable(typeVariableBindings[i], completion);
+ }
+ completion.append('>');
+ completion.append(' ');
+ }
+
+ //// Return type
+ createType(method.returnType, completion);
+ completion.append(' ');
+
+ //// Selector
+ completion.append(method.selector);
+
+ completion.append('(');
+
+ ////Parameters
+ TypeBinding[] parameterTypes = method.parameters;
+ int length = parameterTypes.length;
+ for (int i = 0; i < length; i++) {
+ if(i != 0) {
+ completion.append(',');
+ completion.append(' ');
+ }
+ createType(parameterTypes[i], completion);
+ completion.append(' ');
+ if(parameterNames != null){
+ completion.append(parameterNames[i]);
+ } else {
+ completion.append('%');
+ }
+ }
+
+ completion.append(')');
+
+ //// Exceptions
+ ReferenceBinding[] exceptions = method.thrownExceptions;
+
+ if (exceptions != null && exceptions.length > 0){
+ completion.append(' ');
+ completion.append(THROWS);
+ completion.append(' ');
+ for(int i = 0; i < exceptions.length ; i++){
+ if(i != 0) {
+ completion.append(' ');
+ completion.append(',');
+ }
+ createType(exceptions[i], completion);
+ }
+ }
+ }
private void findMethods(
char[] selector,
TypeBinding[] argTypes,
@@ -3435,7 +4106,8 @@
}
}
private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
- ReferenceBinding bindingType = method.declaringClass;
+ TypeBinding erasure = method.declaringClass.erasure();
+ if(!(erasure instanceof ReferenceBinding)) return null;
char[][] parameterNames = null;
@@ -3445,8 +4117,8 @@
return CharOperation.NO_CHAR_CHAR;
}
// look into the corresponding unit if it is available
- if (bindingType instanceof SourceTypeBinding){
- SourceTypeBinding sourceType = (SourceTypeBinding) bindingType;
+ if (erasure instanceof SourceTypeBinding){
+ SourceTypeBinding sourceType = (SourceTypeBinding) erasure;
if (sourceType.scope != null){
TypeDeclaration parsedType;
@@ -3467,6 +4139,9 @@
}
// look into the model
if(parameterNames == null){
+
+ ReferenceBinding bindingType = (ReferenceBinding)erasure;
+
char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
Object type = this.typeCache.get(compoundName);
@@ -3484,18 +4159,21 @@
}
if(sourceType != null) {
- SourceMethod[] sourceMethods = ((SourceTypeElementInfo) sourceType).getMethodHandles();
- int len = sourceMethods.length;
- for(int i = 0; i < len ; i++){
- SourceMethod sourceMethod = sourceMethods[i];
- String[] argTypeSignatures = sourceMethod.getParameterTypes();
-
- if(argTypeSignatures != null &&
- CharOperation.equals(method.selector,sourceMethod.getElementName().toCharArray()) &&
- equalSignatures(parameterTypeNames, argTypeSignatures)){
+ IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle();
+
+ String[] parameterTypeSignatures = new String[length];
+ for (int i = 0; i < length; i++) {
+ parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
+ }
+ IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
+ IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);
+
+ if(foundMethods != null) {
+ int len = foundMethods.length;
+ if(len == 1) {
try {
+ SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
- break;
} catch (JavaModelException e) {
// method doesn't exist: ignore
}
@@ -3506,28 +4184,18 @@
return parameterNames;
}
- private boolean equalSignatures(char[][] typeNames, String[] typeSignatures) {
- if (typeNames == null || typeSignatures == null)
- return false;
- if (typeNames.length != typeSignatures.length)
- return false;
-
- for (int i = typeNames.length; --i >= 0;)
- if (!CharOperation.equals(typeNames[i], Signature.toCharArray(typeSignatures[i].toCharArray())))
- return false;
- return true;
- }
-
private void findNestedTypes(
char[] typeName,
SourceTypeBinding currentType,
Scope scope,
+ boolean proposeAllMemberTypes,
ObjectVector typesFound) {
if (typeName == null)
return;
int typeLength = typeName.length;
+ SourceTypeBinding nextTypeToIgnore = null;
while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
switch (scope.kind) {
@@ -3545,12 +4213,23 @@
if (!localType.isAnonymousType()) {
if (this.isForbidden(localType))
continue next;
+
if (typeLength > localType.sourceName.length)
continue next;
if (!CharOperation.prefixEquals(typeName, localType.sourceName, false
/* ignore case */
))
continue next;
+
+ if(PROPOSE_MEMBER_TYPES) {
+ if(this.assistNodeIsClass) {
+ if(!localType.isClass()) continue next;
+ } else if(this.assistNodeIsInterface) {
+ if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!localType.isAnnotationType()) continue next;
+ }
+ }
int relevance = computeBaseRelevance();
relevance += computeRelevanceForInterestingProposal();
@@ -3583,7 +4262,9 @@
break;
case Scope.CLASS_SCOPE :
- findMemberTypes(typeName, scope.enclosingSourceType(), scope, currentType, false, typesFound);
+ SourceTypeBinding enclosingSourceType = scope.enclosingSourceType();
+ findMemberTypes(typeName, enclosingSourceType, scope, currentType, false, false, false, proposeAllMemberTypes, nextTypeToIgnore, typesFound);
+ nextTypeToIgnore = enclosingSourceType;
if (typeLength == 0)
return; // do not search outside the class scope if no prefix was provided
break;
@@ -3605,6 +4286,58 @@
this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
}
+ private void findParameterizedType(TypeReference ref) {
+ ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
+ if(refBinding != null) {
+ char[] packageName = refBinding.qualifiedPackageName();
+ char[] typeName = refBinding.qualifiedSourceName();
+
+ int accessibility = IAccessRule.K_ACCESSIBLE;
+ if(refBinding.hasRestrictedAccess()) {
+ AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(refBinding);
+ if(accessRestriction != null) {
+ switch (accessRestriction.getProblemId()) {
+ case IProblem.ForbiddenReference:
+ if (this.options.checkForbiddenReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_NON_ACCESSIBLE;
+ break;
+ case IProblem.DiscouragedReference:
+ if (this.options.checkDiscouragedReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_DISCOURAGED;
+ break;
+ }
+ }
+ }
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
+ relevance += computeRelevanceForExpectingType(refBinding);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
+
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(getSignature(refBinding));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(CharOperation.NO_CHAR);
+ proposal.setFlags(refBinding.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setRelevance(relevance);
+ proposal.setAccessibility(accessibility);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ }
private void findTypeParameters(char[] token, Scope scope) {
if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;
@@ -3675,22 +4408,60 @@
if (token == null)
return;
+ // do not propose type if completion token is empty
+ boolean skip = false;
+ if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) {
+ if(!assistNodeIsConstructor) {
+ return;
+ }
+ skip = true;
+ }
+
boolean proposeType = !this.requestor.isIgnored(CompletionProposal.TYPE_REF);
+ boolean proposeAllMemberTypes = !this.assistNodeIsConstructor && PROPOSE_MEMBER_TYPES;
+
ObjectVector typesFound = new ObjectVector();
- if (proposeType && scope.enclosingSourceType() != null) {
- findNestedTypes(token, scope.enclosingSourceType(), scope, typesFound);
- findTypeParameters(token, scope);
+ if (!skip && proposeType && scope.enclosingSourceType() != null) {
+ findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
+ if(!assistNodeIsConstructor) {
+ // don't propose type parmaters if the completion is a constructor ('new |')
+ findTypeParameters(token, scope);
+ }
}
- if (proposeType && this.unitScope != null) {
+ if (!skip && proposeType && this.unitScope != null) {
+ ReferenceBinding outerInvocationType = scope.enclosingSourceType();
+ if(outerInvocationType != null) {
+ ReferenceBinding temp = outerInvocationType.enclosingType();
+ while(temp != null) {
+ outerInvocationType = temp;
+ temp = temp.enclosingType();
+ }
+ }
+
int typeLength = token.length;
SourceTypeBinding[] types = this.unitScope.topLevelTypes;
for (int i = 0, length = types.length; i < length; i++) {
SourceTypeBinding sourceType = types[i];
+ if(isForbidden(sourceType)) continue;
+
+ if(proposeAllMemberTypes &&
+ sourceType != outerInvocationType &&
+ PROPOSE_MEMBER_TYPES) {
+ findSubMemberTypes(
+ token,
+ sourceType,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ typesFound);
+ }
+
if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
@@ -3699,9 +4470,17 @@
if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)) continue;
this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
-
- if(isForbidden(sourceType)) continue;
-
+
+ if(PROPOSE_MEMBER_TYPES) {
+ if(this.assistNodeIsClass) {
+ if(!sourceType.isClass()) continue;
+ } else if(this.assistNodeIsInterface) {
+ if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!sourceType.isAnnotationType()) continue;
+ }
+ }
+
int relevance = computeBaseRelevance();
relevance += computeRelevanceForInterestingProposal();
relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
@@ -3713,7 +4492,7 @@
relevance += computeRelevanceForAnnotation();
} else if (sourceType.isInterface()) {
relevance += computeRelevanceForInterface();
- } else {
+ } else if(sourceType.isClass()){
relevance += computeRelevanceForClass();
relevance += computeRelevanceForException(sourceType.sourceName);
}
@@ -3736,8 +4515,8 @@
}
}
- if(proposeType) {
- this.findTypesFromStaticImports(token, scope, typesFound);
+ if(!skip && proposeType) {
+ this.findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
}
if (token.length == 0) {
@@ -3746,17 +4525,26 @@
if(this.expectedTypes[i] instanceof ReferenceBinding) {
ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
+ if(refBinding.isTypeVariable() && assistNodeIsConstructor) {
+ // don't propose type variable if the completion is a constructor ('new |')
+ continue next;
+ }
+
int accessibility = IAccessRule.K_ACCESSIBLE;
if(refBinding.hasRestrictedAccess()) {
AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(refBinding);
if(accessRestriction != null) {
switch (accessRestriction.getProblemId()) {
case IProblem.ForbiddenReference:
- if(this.options.checkForbiddenReference) return;
+ if (this.options.checkForbiddenReference) {
+ continue next;
+ }
accessibility = IAccessRule.K_NON_ACCESSIBLE;
break;
case IProblem.DiscouragedReference:
- if(this.options.checkDiscouragedReference) return;
+ if (this.options.checkDiscouragedReference) {
+ continue next;
+ }
accessibility = IAccessRule.K_DISCOURAGED;
break;
}
@@ -3766,14 +4554,14 @@
boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
// top level types of the current unit are already proposed.
- if(!inSameUnit || (inSameUnit && refBinding.isMemberType())) {
+ if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) {
char[] packageName = refBinding.qualifiedPackageName();
char[] typeName = refBinding.sourceName();
char[] completionName = typeName;
boolean isQualified = false;
if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
- if (mustQualifyType(packageName, typeName)) {
+ if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
if (packageName == null || packageName.length == 0)
if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
continue next; // ignore types from the default package from outside it
@@ -3782,6 +4570,16 @@
}
}
+ if(PROPOSE_MEMBER_TYPES) {
+ if(this.assistNodeIsClass) {
+ if(!refBinding.isClass()) continue next;
+ } else if(this.assistNodeIsInterface) {
+ if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!refBinding.isAnnotationType()) continue next;
+ }
+ }
+
int relevance = computeBaseRelevance();
relevance += computeRelevanceForInterestingProposal();
relevance += computeRelevanceForCaseMatching(token, typeName);
@@ -3820,10 +4618,21 @@
}
} else {
if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- findKeywords(token, baseTypes);
+ findKeywords(token, baseTypes, false);
}
if(proposeType) {
- this.nameEnvironment.findTypes(token, this);
+ int l = typesFound.size();
+ for (int i = 0; i < l; i++) {
+ ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
+ char[] fullyQualifiedTypeName =
+ CharOperation.concat(
+ typeFound.qualifiedPackageName(),
+ typeFound.qualifiedSourceName(),
+ '.');
+ this.knownTypes.put(fullyQualifiedTypeName, this);
+ }
+ this.nameEnvironment.findTypes(token, proposeAllMemberTypes, this);
+ acceptTypes();
}
if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
this.nameEnvironment.findPackages(token, this);
@@ -3874,11 +4683,15 @@
if(accessRestriction != null) {
switch (accessRestriction.getProblemId()) {
case IProblem.ForbiddenReference:
- if(this.options.checkForbiddenReference) return;
+ if (this.options.checkForbiddenReference) {
+ continue;
+ }
accessibility = IAccessRule.K_NON_ACCESSIBLE;
break;
case IProblem.DiscouragedReference:
- if(this.options.checkDiscouragedReference) return;
+ if (this.options.checkDiscouragedReference) {
+ continue;
+ }
accessibility = IAccessRule.K_DISCOURAGED;
break;
}
@@ -3898,7 +4711,7 @@
relevance += computeRelevanceForAnnotation();
} else if (sourceType.isInterface()) {
relevance += computeRelevanceForInterface();
- } else {
+ } else if (sourceType.isClass()) {
relevance += computeRelevanceForClass();
relevance += computeRelevanceForException(sourceType.sourceName);
}
@@ -3923,14 +4736,15 @@
}
if(proposeType) {
- this.nameEnvironment.findTypes(qualifiedName, this);
+ this.nameEnvironment.findTypes(qualifiedName, false, this);
+ acceptTypes();
}
if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
this.nameEnvironment.findPackages(qualifiedName, this);
}
}
- private void findTypesFromStaticImports(char[] token, Scope scope, ObjectVector typesFound) {
+ private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
ImportBinding[] importBindings = scope.compilationUnitScope().imports;
for (int i = 0; i < importBindings.length; i++) {
ImportBinding importBinding = importBindings[i];
@@ -3945,6 +4759,10 @@
scope,
scope.enclosingSourceType(),
true,
+ true,
+ true,
+ proposeAllMemberTypes,
+ null,
typesFound);
}
} else {
@@ -3962,10 +4780,21 @@
typesFound.add(typeBinding);
+ if(PROPOSE_MEMBER_TYPES) {
+ if(this.assistNodeIsClass) {
+ if(!typeBinding.isClass()) continue;
+ } else if(this.assistNodeIsInterface) {
+ if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!typeBinding.isAnnotationType()) continue;
+ }
+ }
+
int relevance = computeBaseRelevance();
relevance += computeRelevanceForInterestingProposal();
relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
relevance += computeRelevanceForExpectingType(typeBinding);
+ relevance += computeRelevanceForQualification(false);
relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
if (typeBinding.isClass()) {
@@ -4420,7 +5249,7 @@
}
}
} else if(parent instanceof Assignment) {
- TypeBinding binding = ((Assignment)parent).resolvedType;
+ TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
if(binding != null) {
addExpectedType(binding);
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java
index f242334..0d8f71e 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java
@@ -28,7 +28,7 @@
* Nested type names are in the qualified form "A.I".
* The default package is represented by an empty array.
*/
- public void acceptType(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
+ public void acceptType(char[] packageName, char[] typeName, char[][] enclosingTypeNames, int modifiers, AccessRestriction accessRestriction);
// /**
// * One result of the search consists of a new annotation.
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
index f16a7b1..39b98f0 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
@@ -14,7 +14,6 @@
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.core.BinaryType;
import org.eclipse.jdt.internal.core.NameLookup;
@@ -46,15 +45,46 @@
protected char[][] parameterPackageNames;
protected char[][] parameterTypeNames;
+ protected char[] originalSignature;
+
protected int accessibility = IAccessRule.K_ACCESSIBLE;
- protected char[][] findMethodParameterNames(char[] signatureType, char[] selector, char[][] paramTypeNames){
- if(signatureType == null) return null;
+ protected boolean isConstructor = false;
+
+ protected char[][] createDefaultParameterNames(int length) {
+ char[][] parameterNames;
+ switch (length) {
+ case 0 :
+ parameterNames = new char[length][];
+ break;
+ case 1 :
+ parameterNames = ARGS1;
+ break;
+ case 2 :
+ parameterNames = ARGS2;
+ break;
+ case 3 :
+ parameterNames = ARGS3;
+ break;
+ case 4 :
+ parameterNames = ARGS4;
+ break;
+ default :
+ parameterNames = new char[length][];
+ for (int i = 0; i < length; i++) {
+ parameterNames[i] = CharOperation.concat(ARG, String.valueOf(i).toCharArray());
+ }
+ break;
+ }
+ return parameterNames;
+ }
+ protected char[][] findMethodParameterNames(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] paramTypeNames){
+ if(paramTypeNames == null || declaringTypeName == null) return null;
- char[] tName = Signature.toCharArray(signatureType);
char[][] parameterNames = null;
int length = paramTypeNames.length;
+ char[] tName = CharOperation.concat(declaringTypePackageName,declaringTypeName,'.');
Object cachedType = this.completionEngine.typeCache.get(tName);
IType type = null;
@@ -94,32 +124,9 @@
}
}
-// default parameters name
+ // default parameters name
if(parameterNames == null) {
- switch (length) {
- case 0 :
- parameterNames = new char[length][];
- break;
- case 1 :
- parameterNames = ARGS1;
- break;
- case 2 :
- parameterNames = ARGS2;
- break;
- case 3 :
- parameterNames = ARGS3;
- break;
- case 4 :
- parameterNames = ARGS4;
- break;
- default :
- parameterNames = new char[length][];
- for (int i = 0; i < length; i++) {
- parameterNames[i] = CharOperation.concat(ARG, String.valueOf(i).toCharArray());
- }
- break;
- }
-
+ parameterNames = createDefaultParameterNames(length);
}
return parameterNames;
@@ -150,82 +157,6 @@
return this.parameterTypeNames;
}
- protected char[][] findMethodParameterNames(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] paramPackageNames, char[][] paramTypeNames){
- if(paramTypeNames == null) return null;
-
- char[][] parameterNames = null;
- int length = paramTypeNames.length;
-
- char[] tName = CharOperation.concat(declaringTypePackageName,declaringTypeName,'.');
- Object cachedType = this.completionEngine.typeCache.get(tName);
-
- IType type = null;
- if(cachedType != null) {
- if(cachedType != NO_ATTACHED_SOURCE && cachedType instanceof BinaryType) {
- type = (BinaryType)cachedType;
- }
- } else {
- // TODO (david) shouldn't it be NameLookup.ACCEPT_ALL ?
- type = this.nameLookup.findType(new String(tName), false, NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES);
- if(type instanceof BinaryType){
- if(((BinaryType)type).getSourceMapper() != null) {
- this.completionEngine.typeCache.put(tName, type);
- } else {
- this.completionEngine.typeCache.put(tName, NO_ATTACHED_SOURCE);
- type = null;
- }
- } else {
- type = null;
- }
- }
-
- if(type != null) {
- String[] args = new String[length];
- for(int i = 0; i< length ; i++){
- char[] parameterType = CharOperation.concat(paramPackageNames[i],paramTypeNames[i],'.');
- args[i] = Signature.createTypeSignature(parameterType,true);
- }
- IMethod method = type.getMethod(new String(selector),args);
- try{
- parameterNames = new char[length][];
- String[] params = method.getParameterNames();
- for(int i = 0; i< length ; i++){
- parameterNames[i] = params[i].toCharArray();
- }
- } catch(JavaModelException e){
- parameterNames = null;
- }
- }
- // default parameters name
- if(parameterNames == null) {
- switch (length) {
- case 0 :
- parameterNames = new char[length][];
- break;
- case 1 :
- parameterNames = ARGS1;
- break;
- case 2 :
- parameterNames = ARGS2;
- break;
- case 3 :
- parameterNames = ARGS3;
- break;
- case 4 :
- parameterNames = ARGS4;
- break;
- default :
- parameterNames = new char[length][];
- for (int i = 0; i < length; i++) {
- parameterNames[i] = CharOperation.concat(ARG, String.valueOf(i).toCharArray());
- }
- break;
- }
-
- }
- return parameterNames;
- }
-
protected void setDeclarationPackageName(char[] declarationPackageName) {
this.declarationPackageName = declarationPackageName;
}
@@ -253,4 +184,11 @@
protected void setAccessibility(int kind) {
this.accessibility = kind;
}
+
+ protected void setIsContructor(boolean isConstructor) {
+ this.isConstructor = isConstructor;
+ }
+ public void setOriginalSignature(char[] originalSignature) {
+ this.originalSignature = originalSignature;
+ }
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
index 610fe4c..739943b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
@@ -131,9 +131,20 @@
this.parser = new SelectionParser(problemReporter);
}
- public void acceptType(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction) {
- if (CharOperation.equals(typeName, this.selectedIdentifier)) {
- if(mustQualifyType(packageName, typeName)) {
+ public void acceptType(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, int modifiers, AccessRestriction accessRestriction) {
+ char[] typeName = enclosingTypeNames == null ?
+ simpleTypeName :
+ CharOperation.concat(
+ CharOperation.concatWith(enclosingTypeNames, '.'),
+ simpleTypeName,
+ '.');
+
+ if (CharOperation.equals(simpleTypeName, this.selectedIdentifier)) {
+ char[] flatEnclosingTypeNames =
+ enclosingTypeNames == null || enclosingTypeNames.length == 0 ?
+ null :
+ CharOperation.concatWith(enclosingTypeNames, '.');
+ if(mustQualifyType(packageName, simpleTypeName, flatEnclosingTypeNames, modifiers)) {
int length = 0;
int kind = modifiers & (IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation);
switch (kind) {
@@ -601,20 +612,23 @@
char[][] tokens = ((SelectionOnImportReference) importReference).tokens;
this.noProposal = false;
this.requestor.acceptPackage(CharOperation.concatWith(tokens, '.'));
- this.nameEnvironment.findTypes(CharOperation.concatWith(tokens, '.'), this);
+ this.nameEnvironment.findTypes(CharOperation.concatWith(tokens, '.'), false, this);
- if(importReference.isStatic()) {
- this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
- if ((this.unitScope = parsedUnit.scope) != null) {
- int tokenCount = tokens.length;
- char[] lastToken = tokens[tokenCount - 1];
- char[][] qualifierTokens = CharOperation.subarray(tokens, 0, tokenCount - 1);
-
+ this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+ if ((this.unitScope = parsedUnit.scope) != null) {
+ int tokenCount = tokens.length;
+ char[] lastToken = tokens[tokenCount - 1];
+ char[][] qualifierTokens = CharOperation.subarray(tokens, 0, tokenCount - 1);
+
+ if(qualifierTokens != null && qualifierTokens.length > 0) {
Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
if(binding != null && binding instanceof ReferenceBinding) {
ReferenceBinding ref = (ReferenceBinding) binding;
- selectStaticFieldFromStaticImport(parsedUnit, lastToken, ref);
- selectStaticMethodFromStaticImport(parsedUnit, lastToken, ref);
+ selectMemberTypeFromImport(parsedUnit, lastToken, ref, importReference.isStatic());
+ if(importReference.isStatic()) {
+ selectStaticFieldFromStaticImport(parsedUnit, lastToken, ref);
+ selectStaticMethodFromStaticImport(parsedUnit, lastToken, ref);
+ }
}
}
}
@@ -623,7 +637,7 @@
if(!this.acceptedAnswer) {
acceptQualifiedTypes();
if (!this.acceptedAnswer) {
- this.nameEnvironment.findTypes(this.selectedIdentifier, this);
+ this.nameEnvironment.findTypes(this.selectedIdentifier, false, this);
// try with simple type name
if(!this.acceptedAnswer) {
acceptQualifiedTypes();
@@ -637,7 +651,7 @@
}
}
}
- if (parsedUnit.types != null) {
+ if (parsedUnit.types != null || parsedUnit.isPackageInfo()) {
if(selectDeclaration(parsedUnit))
return;
this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
@@ -645,7 +659,9 @@
try {
this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
parsedUnit.scope.faultInTypes();
- ASTNode node = parseBlockStatements(parsedUnit, selectionSourceStart);
+ ASTNode node = null;
+ if (parsedUnit.types != null)
+ node = parseBlockStatements(parsedUnit, selectionSourceStart);
if(DEBUG) {
System.out.println("SELECTION - AST :"); //$NON-NLS-1$
System.out.println(parsedUnit.toString());
@@ -670,7 +686,7 @@
// only reaches here if no selection could be derived from the parsed tree
// thus use the selected source and perform a textual type search
if (!this.acceptedAnswer) {
- this.nameEnvironment.findTypes(this.selectedIdentifier, this);
+ this.nameEnvironment.findTypes(this.selectedIdentifier, false, this);
// accept qualified types only if no unqualified type was accepted
if(!this.acceptedAnswer) {
@@ -695,6 +711,25 @@
}
}
+ private void selectMemberTypeFromImport(CompilationUnitDeclaration parsedUnit, char[] lastToken, ReferenceBinding ref, boolean staticOnly) {
+ int fieldLength = lastToken.length;
+ ReferenceBinding[] memberTypes = ref.memberTypes();
+ next : for (int j = 0; j < memberTypes.length; j++) {
+ ReferenceBinding memberType = memberTypes[j];
+
+ if (fieldLength > memberType.sourceName.length)
+ continue next;
+
+ if (staticOnly && !memberType.isStatic())
+ continue next;
+
+ if (!CharOperation.equals(lastToken, memberType.sourceName, true))
+ continue next;
+
+ this.selectFrom(memberType, parsedUnit, false);
+ }
+ }
+
private void selectStaticFieldFromStaticImport(CompilationUnitDeclaration parsedUnit, char[] lastToken, ReferenceBinding ref) {
int fieldLength = lastToken.length;
FieldBinding[] fields = ref.fields();
@@ -777,7 +812,7 @@
ReferenceBinding typeBinding = (ReferenceBinding) binding;
if(typeBinding instanceof ProblemReferenceBinding) {
- typeBinding = ((ProblemReferenceBinding) typeBinding).original;
+ typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch;
}
if (typeBinding == null) return;
if (isLocal(typeBinding) && this.requestor instanceof SelectionRequestor) {
@@ -963,6 +998,13 @@
public void selectType(ISourceType sourceType, char[] typeName, SourceTypeElementInfo[] topLevelTypes, boolean searchInEnvironment) {
try {
this.acceptedAnswer = false;
+
+ // only the type erasure are returned by IType.resolvedType(...)
+ if (CharOperation.indexOf('<', typeName) != -1) {
+ char[] typeSig = Signature.createCharArrayTypeSignature(typeName, false/*not resolved*/);
+ typeSig = Signature.getTypeErasure(typeSig);
+ typeName = Signature.toCharArray(typeSig);
+ }
// find the outer most type
ISourceType outerType = sourceType;
@@ -1045,7 +1087,7 @@
// thus use the selected source and perform a textual type search
if (!this.acceptedAnswer && searchInEnvironment) {
if (this.selectedIdentifier != null) {
- this.nameEnvironment.findTypes(typeName, this);
+ this.nameEnvironment.findTypes(typeName, false, this);
// accept qualified types only if no unqualified type was accepted
if(!this.acceptedAnswer) {
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java
index dda5b60..fb3e117 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java
@@ -14,4 +14,5 @@
char[] getToken();
char[][] getPossibleKeywords();
+ boolean canCompleteEmptyToken();
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java
index 22fd7a2..4124ceb 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java
@@ -16,6 +16,8 @@
public class CompletionOnKeyword1 extends SingleTypeReference implements CompletionOnKeyword {
private char[][] possibleKeywords;
+ public boolean canCompleteEmptyToken;
+
public CompletionOnKeyword1(char[] token, long pos, char[] possibleKeyword) {
this(token, pos, new char[][]{possibleKeyword});
}
@@ -23,6 +25,9 @@
super(token, pos);
this.possibleKeywords = possibleKeywords;
}
+ public boolean canCompleteEmptyToken() {
+ return this.canCompleteEmptyToken;
+ }
public char[] getToken() {
return token;
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java
index fbb03f7..41c6e65 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java
@@ -20,6 +20,9 @@
this.token = token;
this.possibleKeywords = possibleKeywords;
}
+ public boolean canCompleteEmptyToken() {
+ return false;
+ }
public char[] getToken() {
return token;
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java
index 20a0716..da672e1 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java
@@ -24,6 +24,9 @@
this.token = token;
this.possibleKeywords = possibleKeywords;
}
+ public boolean canCompleteEmptyToken() {
+ return false;
+ }
public char[] getToken() {
return token;
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java
index d40546b..0654ac1 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java
@@ -60,6 +60,16 @@
output.append("<CompleteOnMessageSend:"); //$NON-NLS-1$
if (!receiver.isImplicitThis()) receiver.printExpression(0, output).append('.'); //$NON-NLS-1$
+ if (this.typeArguments != null) {
+ output.append('<');//$NON-NLS-1$
+ int max = typeArguments.length - 1;
+ for (int j = 0; j < max; j++) {
+ typeArguments[j].print(0, output);
+ output.append(", ");//$NON-NLS-1$
+ }
+ typeArguments[max].print(0, output);
+ output.append('>');
+ }
output.append(selector).append('('); //$NON-NLS-1$
if (arguments != null) {
for (int i = 0; i < arguments.length; i++) {
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java
index 7d40ec9..a7f415d 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java
@@ -29,6 +29,7 @@
public class CompletionOnSingleTypeReference extends SingleTypeReference {
public boolean isCompletionNode;
+public boolean isConstructorType;
public CompletionOnFieldType fieldTypeCompletionNode;
public CompletionOnSingleTypeReference(char[] source, long pos) {
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
index 2038322..383cb95 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -299,6 +299,14 @@
}
}
+ if(this.genericsPtr > -1) {
+ ASTNode node = this.genericsStack[this.genericsPtr];
+ if(node instanceof Wildcard && ((Wildcard)node).bound == this.assistNode){
+ buildMoreGenericsCompletionContext(node);
+ return;
+ }
+ }
+
if(this.currentElement instanceof RecoveredType || this.currentElement instanceof RecoveredMethod) {
if(this.currentElement instanceof RecoveredType) {
RecoveredType recoveredType = (RecoveredType)this.currentElement;
@@ -375,8 +383,7 @@
return;
}
}
- if(node == this.assistNode ||
- ((Wildcard)node).bound == this.assistNode){
+ if(node == this.assistNode){
buildMoreGenericsCompletionContext(node);
}
}
@@ -510,7 +517,7 @@
int length = expressionLengthStack[expressionLengthPtr];
// search previous arguments if missing
- if(expressionLengthPtr > 0 && length == 1) {
+ if(this.expressionPtr > 0 && this.expressionLengthPtr > 0 && length == 1) {
int start = (int) (identifierPositionStack[selector] >>> 32);
if(this.expressionStack[expressionPtr-1] != null && this.expressionStack[expressionPtr-1].sourceStart > start) {
length += expressionLengthStack[expressionLengthPtr-1];
@@ -544,9 +551,19 @@
// remove selector
this.identifierPtr--;
- this.identifierLengthStack[this.identifierLengthPtr]--;
+ if(this.genericsPtr > -1 && this.genericsLengthPtr > -1 && this.genericsLengthStack[this.genericsLengthPtr] > 0) {
+ // is inside a paremeterized method: bar.<X>.foo
+ this.identifierLengthPtr--;
+ } else {
+ this.identifierLengthStack[this.identifierLengthPtr]--;
+ }
// consume the receiver
- messageSend.receiver = this.getUnspecifiedReference();
+ int identifierLength = this.identifierLengthStack[this.identifierLengthPtr];
+ if(this.identifierPtr > -1 && identifierLength > 0 && this.identifierPtr + 1 >= identifierLength) {
+ messageSend.receiver = this.getUnspecifiedReference();
+ } else {
+ messageSend = null;
+ }
break;
case SUPER_RECEIVER:
messageSend.receiver = new SuperReference(0, 0);
@@ -841,7 +858,11 @@
if(prevKind == K_PARAMETERIZED_CAST) {
ref = computeQualifiedGenericsFromRightSide(ref, 0);
}
- currentElement = currentElement.add(ref, 0);
+ if(currentElement instanceof RecoveredType) {
+ currentElement = currentElement.add(new CompletionOnFieldType(ref, false), 0);
+ } else {
+ currentElement = currentElement.add(ref, 0);
+ }
} else if (currentElement.enclosingMethod().methodDeclaration.isConstructor()) {
currentElement = currentElement.add((TypeReference)node, 0);
}
@@ -900,6 +921,9 @@
} else {
type = getTypeReference(0);
}
+ if(type instanceof CompletionOnSingleTypeReference) {
+ ((CompletionOnSingleTypeReference)type).isConstructorType = true;
+ }
allocExpr.type = type;
allocExpr.sourceStart = type.sourceStart;
allocExpr.sourceEnd = type.sourceEnd;
@@ -1144,7 +1168,12 @@
// remove selector
this.identifierPtr--;
- this.identifierLengthStack[this.identifierLengthPtr]--;
+ if(this.genericsPtr > -1 && this.genericsLengthPtr > -1 && this.genericsLengthStack[this.genericsLengthPtr] > 0) {
+ // is inside a paremeterized method: bar.<X>.foo
+ this.identifierLengthPtr--;
+ } else {
+ this.identifierLengthStack[this.identifierLengthPtr]--;
+ }
// consume the receiver
messageSend.receiver = this.getUnspecifiedReference();
break;
@@ -1197,8 +1226,10 @@
// creates an allocation expression
CompletionOnQualifiedAllocationExpression allocExpr = new CompletionOnQualifiedAllocationExpression();
allocExpr.arguments = arguments;
- pushOnGenericsLengthStack(0);
- pushOnGenericsIdentifiersLengthStack(identifierLengthStack[identifierLengthPtr]);
+ if(this.genericsLengthPtr < 0) {
+ pushOnGenericsLengthStack(0);
+ pushOnGenericsIdentifiersLengthStack(identifierLengthStack[identifierLengthPtr]);
+ }
allocExpr.type = super.getTypeReference(0); // we don't want a completion node here, so call super
if (invocType == QUALIFIED_ALLOCATION) {
allocExpr.enclosingInstance = this.expressionStack[qualifierExprPtr];
@@ -1372,6 +1403,62 @@
}
return false;
}
+private void classHeaderExtendsOrImplements(boolean isInterface) {
+ if (currentElement != null
+ && currentToken == TokenNameIdentifier
+ && this.cursorLocation+1 >= scanner.startPosition
+ && this.cursorLocation < scanner.currentPosition){
+ this.pushIdentifier();
+ int index = -1;
+ /* check if current awaiting identifier is the completion identifier */
+ if ((index = this.indexOfAssistIdentifier()) > -1) {
+ int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1;
+ RecoveredType recoveredType = (RecoveredType)currentElement;
+ /* filter out cases where scanner is still inside type header */
+ if (!recoveredType.foundOpeningBrace) {
+ TypeDeclaration type = recoveredType.typeDeclaration;
+ if(!isInterface) {
+ char[][] keywords = new char[Keywords.COUNT][];
+ int count = 0;
+
+
+ if(type.superInterfaces == null) {
+ if(type.superclass == null) {
+ keywords[count++] = Keywords.EXTENDS;
+ }
+ keywords[count++] = Keywords.IMPLEMENTS;
+ }
+
+ System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
+
+ if(count > 0) {
+ CompletionOnKeyword1 completionOnKeyword = new CompletionOnKeyword1(
+ identifierStack[ptr],
+ identifierPositionStack[ptr],
+ keywords);
+ completionOnKeyword.canCompleteEmptyToken = true;
+ type.superclass = completionOnKeyword;
+ type.superclass.bits |= ASTNode.IsSuperType;
+ this.assistNode = completionOnKeyword;
+ this.lastCheckPoint = completionOnKeyword.sourceEnd + 1;
+ }
+ } else {
+ if(type.superInterfaces == null) {
+ CompletionOnKeyword1 completionOnKeyword = new CompletionOnKeyword1(
+ identifierStack[ptr],
+ identifierPositionStack[ptr],
+ Keywords.EXTENDS);
+ completionOnKeyword.canCompleteEmptyToken = true;
+ type.superInterfaces = new TypeReference[]{completionOnKeyword};
+ type.superInterfaces[0].bits |= ASTNode.IsSuperType;
+ this.assistNode = completionOnKeyword;
+ this.lastCheckPoint = completionOnKeyword.sourceEnd + 1;
+ }
+ }
+ }
+ }
+ }
+}
/*
* Check whether about to shift beyond the completion token.
* If so, depending on the context, a special node might need to be created
@@ -1537,45 +1624,9 @@
protected void consumeClassHeaderName1() {
super.consumeClassHeaderName1();
- if (currentElement != null
- && currentToken == TokenNameIdentifier
- && this.cursorLocation+1 >= scanner.startPosition
- && this.cursorLocation < scanner.currentPosition){
- this.pushIdentifier();
-
- int index = -1;
- /* check if current awaiting identifier is the completion identifier */
- if ((index = this.indexOfAssistIdentifier()) > -1) {
- int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1;
- RecoveredType recoveredType = (RecoveredType)currentElement;
- /* filter out cases where scanner is still inside type header */
- if (!recoveredType.foundOpeningBrace) {
- char[][] keywords = new char[Keywords.COUNT][];
- int count = 0;
-
- TypeDeclaration type = recoveredType.typeDeclaration;
- if(type.superInterfaces == null) {
- if(type.superclass == null) {
- keywords[count++] = Keywords.EXTENDS;
- }
- keywords[count++] = Keywords.IMPLEMENTS;
- }
-
- System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
-
- if(count > 0) {
- type.superclass = new CompletionOnKeyword1(
- identifierStack[ptr],
- identifierPositionStack[ptr],
- keywords);
- type.superclass.bits |= ASTNode.IsSuperType;
- this.assistNode = type.superclass;
- this.lastCheckPoint = type.superclass.sourceEnd + 1;
- }
- }
- }
- }
+ classHeaderExtendsOrImplements(false);
}
+
protected void consumeClassHeaderExtends() {
pushOnElementStack(K_NEXT_TYPEREF_IS_CLASS);
super.consumeClassHeaderExtends();
@@ -1847,13 +1898,23 @@
}
protected void consumeInsideCastExpression() {
int end = intStack[intPtr--];
- if(this.identifierLengthStack[this.identifierLengthPtr] > 0) {
- pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
- if(this.genericsLengthPtr < 0) {
+ boolean isParameterized =(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_PARAMETERIZED_CAST);
+ if(isParameterized) {
+ popElement(K_PARAMETERIZED_CAST);
+
+ if(this.identifierLengthStack[this.identifierLengthPtr] > 0) {
+ pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
+ }
+ } else {
+ if(this.identifierLengthStack[this.identifierLengthPtr] > 0) {
+ pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
pushOnGenericsLengthStack(0);
}
}
Expression castType = getTypeReference(intStack[intPtr--]);
+ if(isParameterized) {
+ intPtr--;
+ }
castType.sourceEnd = end - 1;
castType.sourceStart = intStack[intPtr--] + 1;
pushOnExpressionStack(castType);
@@ -1861,10 +1922,15 @@
pushOnElementStack(K_CAST_STATEMENT);
}
protected void consumeInsideCastExpressionLL1() {
+ if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_PARAMETERIZED_CAST) {
+ popElement(K_PARAMETERIZED_CAST);
+ }
super.consumeInsideCastExpressionLL1();
pushOnElementStack(K_CAST_STATEMENT);
}
protected void consumeInsideCastExpressionWithQualifiedGenerics() {
+ popElement(K_PARAMETERIZED_CAST);
+
Expression castType;
int end = this.intStack[this.intPtr--];
@@ -1872,6 +1938,7 @@
TypeReference rightSide = getTypeReference(0);
castType = computeQualifiedGenericsFromRightSide(rightSide, dim);
+ this.intPtr--;
castType.sourceEnd = end - 1;
castType.sourceStart = this.intStack[this.intPtr--] + 1;
pushOnExpressionStack(castType);
@@ -1899,33 +1966,7 @@
protected void consumeInterfaceHeaderName1() {
super.consumeInterfaceHeaderName1();
- if (currentElement != null
- && currentToken == TokenNameIdentifier
- && this.cursorLocation+1 >= scanner.startPosition
- && this.cursorLocation < scanner.currentPosition){
- this.pushIdentifier();
-
- int index = -1;
- /* check if current awaiting identifier is the completion identifier */
- if ((index = this.indexOfAssistIdentifier()) > -1) {
- int ptr = this.identifierPtr - this.identifierLengthStack[this.identifierLengthPtr] + index + 1;
- RecoveredType recoveredType = (RecoveredType)currentElement;
- /* filter out cases where scanner is still inside type header */
- if (!recoveredType.foundOpeningBrace) {
- TypeDeclaration type = recoveredType.typeDeclaration;
- if(type.superInterfaces == null) {
- CompletionOnKeyword1 completionOnKeyword = new CompletionOnKeyword1(
- identifierStack[ptr],
- identifierPositionStack[ptr],
- Keywords.EXTENDS);
- type.superInterfaces = new TypeReference[]{completionOnKeyword};
- type.superInterfaces[0].bits |= ASTNode.IsSuperType;
- this.assistNode = completionOnKeyword;
- this.lastCheckPoint = completionOnKeyword.sourceEnd + 1;
- }
- }
- }
- }
+ classHeaderExtendsOrImplements(true);
}
protected void consumeInterfaceHeaderExtends() {
super.consumeInterfaceHeaderExtends();
@@ -1941,16 +1982,31 @@
popElement(K_SELECTOR_INVOCATION_TYPE);
super.consumeMethodInvocationName();
}
+protected void consumeMethodInvocationNameWithTypeArguments() {
+ popElement(K_SELECTOR_QUALIFIER);
+ popElement(K_SELECTOR_INVOCATION_TYPE);
+ super.consumeMethodInvocationNameWithTypeArguments();
+}
protected void consumeMethodInvocationPrimary() {
popElement(K_SELECTOR_QUALIFIER);
popElement(K_SELECTOR_INVOCATION_TYPE);
super.consumeMethodInvocationPrimary();
}
+protected void consumeMethodInvocationPrimaryWithTypeArguments() {
+ popElement(K_SELECTOR_QUALIFIER);
+ popElement(K_SELECTOR_INVOCATION_TYPE);
+ super.consumeMethodInvocationPrimaryWithTypeArguments();
+}
protected void consumeMethodInvocationSuper() {
popElement(K_SELECTOR_QUALIFIER);
popElement(K_SELECTOR_INVOCATION_TYPE);
super.consumeMethodInvocationSuper();
}
+protected void consumeMethodInvocationSuperWithTypeArguments() {
+ popElement(K_SELECTOR_QUALIFIER);
+ popElement(K_SELECTOR_INVOCATION_TYPE);
+ super.consumeMethodInvocationSuperWithTypeArguments();
+}
protected void consumeMethodHeaderName(boolean isAnnotationMethod) {
if(this.indexOfAssistIdentifier() < 0) {
identifierPtr--;
@@ -2287,6 +2343,20 @@
super.consumePrimaryNoNewArrayName();
}
+protected void consumePrimaryNoNewArrayNameSuper() {
+ // this is class literal access, so reset potential receiver
+ this.invocationType = NO_RECEIVER;
+ this.qualifier = -1;
+
+ super.consumePrimaryNoNewArrayNameSuper();
+}
+protected void consumePrimaryNoNewArrayNameThis() {
+ // this is class literal access, so reset potential receiver
+ this.invocationType = NO_RECEIVER;
+ this.qualifier = -1;
+
+ super.consumePrimaryNoNewArrayNameThis();
+}
protected void consumePushPosition() {
super.consumePushPosition();
if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BINARY_OPERATOR) {
@@ -2444,6 +2514,16 @@
this.qualifier = -1;
this.invocationType = NO_RECEIVER;
break;
+ case TokenNameGREATER: // explicit constructor invocation, eg. Fred<X>[(]1, 2)
+ case TokenNameRIGHT_SHIFT: // or fred<X<X>>[(]1, 2)
+ case TokenNameUNSIGNED_RIGHT_SHIFT: //or Fred<X<X<X>>>[(]1, 2)
+ if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SELECTOR) {
+ this.pushOnElementStack(K_SELECTOR_INVOCATION_TYPE, (this.invocationType == QUALIFIED_ALLOCATION) ? QUALIFIED_ALLOCATION : ALLOCATION);
+ this.pushOnElementStack(K_SELECTOR_QUALIFIER, this.qualifier);
+ }
+ this.qualifier = -1;
+ this.invocationType = NO_RECEIVER;
+ break;
}
break;
case TokenNameLBRACE:
@@ -2728,9 +2808,6 @@
}
protected void consumeRightParen() {
super.consumeRightParen();
- if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_PARAMETERIZED_CAST) {
- popElement(K_PARAMETERIZED_CAST);
- }
}
protected void consumeReferenceType1() {
super.consumeReferenceType1();
@@ -2756,10 +2833,46 @@
super.consumeTypeArguments();
popElement(K_BINARY_OPERATOR);
}
+protected void consumeTypeHeaderNameWithTypeParameters() {
+ super.consumeTypeHeaderNameWithTypeParameters();
+
+ TypeDeclaration typeDecl = (TypeDeclaration)this.astStack[this.astPtr];
+ classHeaderExtendsOrImplements((typeDecl.modifiers & AccInterface) != 0);
+}
protected void consumeTypeParameters() {
super.consumeTypeParameters();
popElement(K_BINARY_OPERATOR);
}
+protected void consumeTypeParameterHeader() {
+ super.consumeTypeParameterHeader();
+ TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
+ if(typeParameter.type != null || (typeParameter.bounds != null && typeParameter.bounds.length > 0)) return;
+
+ if (assistIdentifier() == null && this.currentToken == TokenNameIdentifier) { // Test below copied from CompletionScanner.getCurrentIdentifierSource()
+ if (cursorLocation < this.scanner.startPosition && this.scanner.currentPosition == this.scanner.startPosition){ // fake empty identifier got issued
+ this.pushIdentifier();
+ } else if (cursorLocation+1 >= this.scanner.startPosition && cursorLocation < this.scanner.currentPosition){
+ this.pushIdentifier();
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+
+ CompletionOnKeyword1 keyword = new CompletionOnKeyword1(
+ identifierStack[this.identifierPtr],
+ identifierPositionStack[this.identifierPtr],
+ Keywords.EXTENDS);
+ keyword.canCompleteEmptyToken = true;
+ typeParameter.type = keyword;
+
+ this.identifierPtr--;
+ this.identifierLengthPtr--;
+
+ this.assistNode = typeParameter.type;
+ this.lastCheckPoint = typeParameter.type.sourceEnd + 1;
+}
protected void consumeTypeParameters1() {
super.consumeTypeParameter1();
popElement(K_BINARY_OPERATOR);
@@ -2780,6 +2893,34 @@
super.consumeTypeParameter1WithExtendsAndBounds();
popElement(K_EXTENDS_KEYWORD);
}
+protected void consumeWildcard() {
+ super.consumeWildcard();
+ if (assistIdentifier() == null && this.currentToken == TokenNameIdentifier) { // Test below copied from CompletionScanner.getCurrentIdentifierSource()
+ if (cursorLocation < this.scanner.startPosition && this.scanner.currentPosition == this.scanner.startPosition){ // fake empty identifier got issued
+ this.pushIdentifier();
+ } else if (cursorLocation+1 >= this.scanner.startPosition && cursorLocation < this.scanner.currentPosition){
+ this.pushIdentifier();
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+ Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
+ CompletionOnKeyword1 keyword = new CompletionOnKeyword1(
+ identifierStack[this.identifierPtr],
+ identifierPositionStack[this.identifierPtr],
+ new char[][]{Keywords.EXTENDS, Keywords.SUPER} );
+ keyword.canCompleteEmptyToken = true;
+ wildcard.kind = Wildcard.EXTENDS;
+ wildcard.bound = keyword;
+
+ this.identifierPtr--;
+ this.identifierLengthPtr--;
+
+ this.assistNode = wildcard.bound;
+ this.lastCheckPoint = wildcard.bound.sourceEnd + 1;
+}
protected void consumeWildcard1() {
super.consumeWildcard1();
popElement(K_BINARY_OPERATOR);
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
index 7523889..7f8f80f 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
@@ -118,11 +118,6 @@
/* might be completing at eof (e.g. behind a dot) */
if (this.completionIdentifier == null &&
this.startPosition == this.cursorLocation + 1){
- // compute end of empty identifier.
- // if the empty identifier is at the start of a next token the end of
- // empty identifier is the end of the next token (eg. "<empty token>next").
- while(getNextCharAsJavaIdentifierPart()){/*empty*/}
- this.endOfEmptyToken = this.currentPosition - 1;
this.currentPosition = this.startPosition; // for being detected as empty free identifier
return TokenNameIdentifier;
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
index 4771072..5e8d5ec 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
@@ -39,13 +39,13 @@
public static final String OPTION_ArgumentSuffixes =
"org.eclipse.jdt.core.codeComplete.argumentSuffixes"; //$NON-NLS-1$
public static final String OPTION_PerformForbiddenReferenceCheck =
- "org.eclipse.jdt.core.codeComplete.restrictionsCheck"; //$NON-NLS-1$
+ "org.eclipse.jdt.core.codeComplete.forbiddenReferenceCheck"; //$NON-NLS-1$
public static final String OPTION_PerformDiscouragedReferenceCheck =
"org.eclipse.jdt.core.codeComplete.discouragedReferenceCheck"; //$NON-NLS-1$
public static final String ENABLED = "enabled"; //$NON-NLS-1$
public static final String DISABLED = "disabled"; //$NON-NLS-1$
-
+
public boolean checkVisibility = false;
public boolean checkForbiddenReference = false;
public boolean checkDiscouragedReference = false;
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
index eebf89a..469e37e 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
@@ -74,11 +74,16 @@
protected static final int K_METHOD_DELIMITER = ASSIST_PARSER + 3; // whether we are inside a method declaration
protected static final int K_FIELD_INITIALIZER_DELIMITER = ASSIST_PARSER + 4; // whether we are inside a field initializer
protected static final int K_ATTRIBUTE_VALUE_DELIMITER = ASSIST_PARSER + 5; // whether we are inside a annotation attribute valuer
+ protected static final int K_ENUM_CONSTANT_DELIMITER = ASSIST_PARSER + 6; // whether we are inside a field initializer
// selector constants
protected static final int THIS_CONSTRUCTOR = -1;
protected static final int SUPER_CONSTRUCTOR = -2;
+ // enum constant constants
+ protected static final int NO_BODY = 0;
+ protected static final int WITH_BODY = 1;
+
protected boolean isFirst = false;
public AssistParser(ProblemReporter problemReporter) {
@@ -279,6 +284,29 @@
super.consumeEnterMemberValue();
pushOnElementStack(K_ATTRIBUTE_VALUE_DELIMITER, this.identifierPtr);
}
+protected void consumeEnumConstantHeader() {
+ if(this.currentToken == TokenNameLBRACE) {
+ popElement(K_ENUM_CONSTANT_DELIMITER);
+ pushOnElementStack(K_ENUM_CONSTANT_DELIMITER, WITH_BODY);
+ pushOnElementStack(K_FIELD_INITIALIZER_DELIMITER);
+ pushOnElementStack(K_TYPE_DELIMITER);
+ }
+ super.consumeEnumConstantHeader();
+}
+protected void consumeEnumConstantHeaderName() {
+ super.consumeEnumConstantHeaderName();
+ pushOnElementStack(K_ENUM_CONSTANT_DELIMITER);
+}
+protected void consumeEnumConstantWithClassBody() {
+ popElement(K_TYPE_DELIMITER);
+ popElement(K_FIELD_INITIALIZER_DELIMITER);
+ popElement(K_ENUM_CONSTANT_DELIMITER);
+ super.consumeEnumConstantWithClassBody();
+}
+protected void consumeEnumConstantNoClassBody() {
+ popElement(K_ENUM_CONSTANT_DELIMITER);
+ super.consumeEnumConstantNoClassBody();
+}
protected void consumeEnumHeader() {
super.consumeEnumHeader();
pushOnElementStack(K_TYPE_DELIMITER);
@@ -296,31 +324,23 @@
// if we are not in a method (ie. we are not in a local variable initializer)
// then we are entering a field initializer
if (!isInsideMethod()) {
- pushOnElementStack(K_FIELD_INITIALIZER_DELIMITER);
+ if(topKnownElementKind(ASSIST_PARSER) != K_ENUM_CONSTANT_DELIMITER) {
+ if(topKnownElementKind(ASSIST_PARSER, 2) != K_ENUM_CONSTANT_DELIMITER) {
+ pushOnElementStack(K_FIELD_INITIALIZER_DELIMITER);
+ }
+ } else {
+ int info = topKnownElementInfo(ASSIST_PARSER);
+ if(info != NO_BODY) {
+ pushOnElementStack(K_FIELD_INITIALIZER_DELIMITER);
+ }
+ }
+
}
}
protected void consumeInterfaceHeader() {
super.consumeInterfaceHeader();
pushOnElementStack(K_TYPE_DELIMITER);
}
-protected void consumeInternalCompilationUnit() {
- // InternalCompilationUnit ::= PackageDeclaration
- // InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
- // InternalCompilationUnit ::= ImportDeclarations ReduceImports
-}
-protected void consumeInternalCompilationUnitWithTypes() {
- // InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
- // InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
- // InternalCompilationUnit ::= TypeDeclarations
- // InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
- // consume type declarations
- int length;
- if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
- this.compilationUnit.types = new TypeDeclaration[length];
- this.astPtr -= length;
- System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
- }
-}
protected void consumeMethodBody() {
super.consumeMethodBody();
popElement(K_METHOD_DELIMITER);
@@ -693,6 +713,13 @@
case TokenNamesuper: // explicit constructor invocation, eg. super(1, 2)
this.pushOnElementStack(K_SELECTOR, SUPER_CONSTRUCTOR);
break;
+ case TokenNameGREATER: // explicit constructor invocation, eg. Fred<X>[(]1, 2)
+ case TokenNameRIGHT_SHIFT: // or fred<X<X>>[(]1, 2)
+ case TokenNameUNSIGNED_RIGHT_SHIFT: //or Fred<X<X<X>>>[(]1, 2)
+ if(this.identifierPtr > -1) {
+ this.pushOnElementStack(K_SELECTOR, this.identifierPtr);
+ }
+ break;
}
break;
}
@@ -1436,7 +1463,8 @@
if(currentElement != oldElement && !isInsideAttributeValue()) {
if(oldElement instanceof RecoveredInitializer
|| oldElement instanceof RecoveredMethod
- || (oldElement instanceof RecoveredBlock && oldElement.parent instanceof RecoveredInitializer)) {
+ || (oldElement instanceof RecoveredBlock && oldElement.parent instanceof RecoveredInitializer)
+ || (oldElement instanceof RecoveredBlock && oldElement.parent instanceof RecoveredMethod)) {
popUntilElement(K_METHOD_DELIMITER);
popElement(K_METHOD_DELIMITER);
} else if(oldElement instanceof RecoveredType) {
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java
index 1cf0837..b3d6ae4 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java
@@ -19,7 +19,9 @@
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.core.NameLookup;
import org.eclipse.jdt.internal.core.SearchableEnvironment;
public abstract class Engine implements ITypeRequestor {
@@ -31,10 +33,23 @@
public AssistOptions options;
public CompilerOptions compilerOptions;
+ public boolean forbiddenReferenceIsError;
+ public boolean discouragedReferenceIsError;
+
+ public boolean importCachesInitialized = false;
+ public char[][][] importsCache;
+ public ImportBinding[] onDemandImportsCache;
+ public int importCacheCount = 0;
+ public int onDemandImportCacheCount = 0;
+ public char[] currentPackageName = null;
public Engine(Map settings){
this.options = new AssistOptions(settings);
this.compilerOptions = new CompilerOptions(settings);
+ this.forbiddenReferenceIsError =
+ this.compilerOptions.getSeverity(CompilerOptions.ForbiddenReference) == ProblemSeverities.Error;
+ this.discouragedReferenceIsError =
+ this.compilerOptions.getSeverity(CompilerOptions.DiscouragedReference) == ProblemSeverities.Error;
}
/**
@@ -80,47 +95,144 @@
public abstract AssistParser getParser();
+ public void initializeImportCaches() {
+ ImportBinding[] importBindings = this.unitScope.imports;
+ int length = importBindings == null ? 0 : importBindings.length;
+
+ this.currentPackageName = CharOperation.concatWith(unitScope.fPackage.compoundName, '.');
+
+ for (int i = 0; i < length; i++) {
+ ImportBinding importBinding = importBindings[i];
+ if(importBinding.onDemand) {
+ if(this.onDemandImportsCache == null) {
+ this.onDemandImportsCache = new ImportBinding[length - i];
+ }
+ this.onDemandImportsCache[this.onDemandImportCacheCount++] =
+ importBinding;
+ } else {
+ if(!(importBinding.resolvedImport instanceof MethodBinding) ||
+ importBinding instanceof ImportConflictBinding) {
+ if(this.importsCache == null) {
+ this.importsCache = new char[length - i][][];
+ }
+ this.importsCache[this.importCacheCount++] = new char[][]{
+ importBinding.compoundName[importBinding.compoundName.length - 1],
+ CharOperation.concatWith(importBinding.compoundName, '.')
+ };
+ }
+ }
+ }
+
+ this.importCachesInitialized = true;
+ }
+
protected boolean mustQualifyType(
char[] packageName,
- char[] typeName) {
+ char[] typeName,
+ char[] enclosingTypeNames,
+ int modifiers) {
// If there are no types defined into the current CU yet.
if (unitScope == null)
return true;
-
- char[][] compoundPackageName = CharOperation.splitOn('.', packageName);
- char[] readableTypeName = CharOperation.concat(packageName, typeName, '.');
-
- if (CharOperation.equals(unitScope.fPackage.compoundName, compoundPackageName))
+
+ if(!this.importCachesInitialized) {
+ this.initializeImportCaches();
+ }
+
+ char[] fullyQualifiedTypeName = null;
+
+ for (int i = 0; i < this.importCacheCount; i++) {
+ char[][] importName = this.importsCache[i];
+ if(CharOperation.equals(typeName, importName[0])) {
+ if (fullyQualifiedTypeName == null) {
+ fullyQualifiedTypeName =
+ enclosingTypeNames == null || enclosingTypeNames.length == 0
+ ? CharOperation.concat(
+ packageName,
+ typeName,
+ '.')
+ : CharOperation.concat(
+ CharOperation.concat(
+ packageName,
+ enclosingTypeNames,
+ '.'),
+ typeName,
+ '.');
+ }
+ return !CharOperation.equals(fullyQualifiedTypeName, importName[1]);
+ }
+ }
+
+ if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName))
return false;
-
- ImportBinding[] imports = unitScope.imports;
- if (imports != null){
- for (int i = 0, length = imports.length; i < length; i++) {
- if (imports[i].onDemand) {
- if (CharOperation.equals(imports[i].compoundName, compoundPackageName)) {
- for (int j = 0; j < imports.length; j++) {
- if(i != j){
- if(imports[j].onDemand) {
- if(nameEnvironment.findType(typeName, imports[j].compoundName) != null){
- return true;
- }
- } else {
- if(CharOperation.equals(CharOperation.lastSegment(imports[j].readableName(), '.'), typeName)
- && !CharOperation.equals(imports[j].compoundName, CharOperation.splitOn('.', readableTypeName))) {
- return true;
- }
- }
+
+ char[] fullyQualifiedEnclosingTypeName = null;
+
+ for (int i = 0; i < this.onDemandImportCacheCount; i++) {
+ ImportBinding importBinding = this.onDemandImportsCache[i];
+ Binding resolvedImport = importBinding.resolvedImport;
+
+ char[][] importName = importBinding.compoundName;
+ char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+ boolean isFound = false;
+ // resolvedImport is a ReferenceBindng or a PackageBinding
+ if(resolvedImport instanceof ReferenceBinding) {
+ if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
+ if(fullyQualifiedEnclosingTypeName == null) {
+ fullyQualifiedEnclosingTypeName =
+ CharOperation.concat(
+ packageName,
+ enclosingTypeNames,
+ '.');
+ }
+ if(CharOperation.equals(fullyQualifiedEnclosingTypeName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ isFound = (modifiers & IConstants.AccStatic) != 0;
+ } else {
+ isFound = true;
+ }
+ }
+ }
+ } else {
+ if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
+ if(CharOperation.equals(packageName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ isFound = (modifiers & IConstants.AccStatic) != 0;
+ } else {
+ isFound = true;
+ }
+ }
+ }
+ }
+
+ // find potential conflict with another import
+ if(isFound) {
+ for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+ if(i != j) {
+ ImportBinding conflictingImportBinding = this.onDemandImportsCache[j];
+ if(conflictingImportBinding.resolvedImport instanceof ReferenceBinding) {
+ ReferenceBinding refBinding =
+ (ReferenceBinding) conflictingImportBinding.resolvedImport;
+ if (refBinding.getMemberType(typeName) != null) {
+ return true;
+ }
+ } else {
+ char[] conflictingImportName =
+ CharOperation.concatWith(conflictingImportBinding.compoundName, '.');
+
+ if (this.nameEnvironment.nameLookup.findType(
+ String.valueOf(typeName),
+ String.valueOf(conflictingImportName),
+ false,
+ NameLookup.ACCEPT_ALL) != null) {
+ return true;
}
}
- return false; // how do you match p1.p2.A.* ?
}
-
- } else
-
- if (CharOperation.equals(imports[i].readableName(), readableTypeName)) {
- return false;
- }
+ }
+ return false;
}
}
return true;
@@ -203,6 +315,17 @@
lookupEnvironment.reset();
}
+ public static char[] getTypeSignature(TypeBinding typeBinding) {
+ if(typeBinding.isLocalType()) {
+ LocalTypeBinding localTypeBinding = (LocalTypeBinding)typeBinding;
+ if(localTypeBinding.isAnonymousType()) {
+ typeBinding = localTypeBinding.superclass();
+ } else {
+ localTypeBinding.setConstantPoolName(typeBinding.sourceName());
+ }
+ }
+ return typeBinding.signature();
+ }
public static char[] getSignature(Binding binding) {
char[] result = null;
if ((binding.kind() & Binding.TYPE) != 0) {
@@ -212,6 +335,7 @@
if(localTypeBinding.isAnonymousType()) {
typeBinding = localTypeBinding.superclass();
} else {
+ // TODO (david) this code is not necessary any longer (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=99686)
localTypeBinding.setConstantPoolName(typeBinding.sourceName());
}
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java
index 1054de3..f23a87d 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java
@@ -69,9 +69,16 @@
*
* @throws SelectionNodeFound
*/
- public void resolve(ClassScope scope) {
+ private void internalResolve(Scope scope) {
if (this.selectedNode != null) {
- this.selectedNode.resolveType(scope);
+ switch (scope.kind) {
+ case Scope.CLASS_SCOPE:
+ this.selectedNode.resolveType((ClassScope)scope);
+ break;
+ case Scope.METHOD_SCOPE:
+ this.selectedNode.resolveType((MethodScope)scope);
+ break;
+ }
Binding binding = null;
if (this.selectedNode instanceof JavadocFieldReference) {
JavadocFieldReference fieldRef = (JavadocFieldReference) this.selectedNode;
@@ -108,37 +115,28 @@
*
* @throws SelectionNodeFound
*/
+ public void resolve(ClassScope scope) {
+ internalResolve(scope);
+ }
+
+ /**
+ * Resolve selected node if not null and throw exception to let clients know
+ * that it has been found.
+ *
+ * @throws SelectionNodeFound
+ */
+ public void resolve(CompilationUnitScope scope) {
+ internalResolve(scope);
+ }
+
+ /**
+ * Resolve selected node if not null and throw exception to let clients know
+ * that it has been found.
+ *
+ * @throws SelectionNodeFound
+ */
public void resolve(MethodScope scope) {
- if (this.selectedNode != null) {
- this.selectedNode.resolveType(scope);
- Binding binding = null;
- if (this.selectedNode instanceof JavadocFieldReference) {
- JavadocFieldReference fieldRef = (JavadocFieldReference) this.selectedNode;
- binding = fieldRef.binding;
- if (binding == null && fieldRef.methodBinding != null) {
- binding = fieldRef.methodBinding;
- }
- } else if (this.selectedNode instanceof JavadocMessageSend) {
- binding = ((JavadocMessageSend) this.selectedNode).binding;
- } else if (this.selectedNode instanceof JavadocAllocationExpression) {
- binding = ((JavadocAllocationExpression) this.selectedNode).binding;
- } else if (this.selectedNode instanceof JavadocSingleNameReference) {
- binding = ((JavadocSingleNameReference) this.selectedNode).binding;
- } else if (this.selectedNode instanceof JavadocSingleTypeReference) {
- JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) this.selectedNode;
- if (typeRef.packageBinding == null) {
- binding = typeRef.resolvedType;
- }
- } else if (this.selectedNode instanceof JavadocQualifiedTypeReference) {
- JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) this.selectedNode;
- if (typeRef.packageBinding == null) {
- binding = typeRef.resolvedType;
- }
- } else {
- binding = this.selectedNode.resolvedType;
- }
- throw new SelectionNodeFound(binding);
- }
+ internalResolve(scope);
}
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java
index 2818d6d..ed34c72 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java
@@ -15,8 +15,6 @@
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
public class SelectionOnParameterizedQualifiedTypeReference extends ParameterizedQualifiedTypeReference {
@@ -33,19 +31,21 @@
public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
super.resolveType(scope, checkBounds);
- if(this.resolvedType != null && this.resolvedType.isRawType()) {
- ParameterizedTypeBinding parameterizedTypeBinding = scope.createParameterizedType(((RawTypeBinding)this.resolvedType).type, new TypeBinding[0], this.resolvedType.enclosingType());
- throw new SelectionNodeFound(parameterizedTypeBinding);
- }
+ //// removed unnecessary code to solve bug 94653
+ //if(this.resolvedType != null && this.resolvedType.isRawType()) {
+ // ParameterizedTypeBinding parameterizedTypeBinding = scope.createParameterizedType(((RawTypeBinding)this.resolvedType).type, new TypeBinding[0], this.resolvedType.enclosingType());
+ // throw new SelectionNodeFound(parameterizedTypeBinding);
+ //}
throw new SelectionNodeFound(this.resolvedType);
}
public TypeBinding resolveType(ClassScope scope) {
super.resolveType(scope);
- if(this.resolvedType != null && this.resolvedType.isRawType()) {
- ParameterizedTypeBinding parameterizedTypeBinding = scope.createParameterizedType(((RawTypeBinding)this.resolvedType).type, new TypeBinding[0], this.resolvedType.enclosingType());
- throw new SelectionNodeFound(parameterizedTypeBinding);
- }
+ //// removed unnecessary code to solve bug 94653
+ //if(this.resolvedType != null && this.resolvedType.isRawType()) {
+ // ParameterizedTypeBinding parameterizedTypeBinding = scope.createParameterizedType(((RawTypeBinding)this.resolvedType).type, new TypeBinding[0], this.resolvedType.enclosingType());
+ // throw new SelectionNodeFound(parameterizedTypeBinding);
+ //}
throw new SelectionNodeFound(this.resolvedType);
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
index 3597a0d..ae20ae6 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
@@ -154,11 +154,17 @@
// ClassBodyopt produces a null item on the astStak if it produces NO class body
// An empty class body produces a 0 on the length stack.....
- int length;
- if (((length = astLengthStack[astLengthPtr]) == 1)
+
+ if ((astLengthStack[astLengthPtr] == 1)
&& (astStack[astPtr] == null)) {
- if (this.indexOfAssistIdentifier() < 0) {
+
+ int index;
+ if ((index = this.indexOfAssistIdentifier()) < 0) {
+ super.classInstanceCreation(hasClassBody);
+ return;
+ } else if(this.identifierLengthPtr > -1 &&
+ (this.identifierLengthStack[this.identifierLengthPtr] - 1) != index) {
super.classInstanceCreation(hasClassBody);
return;
}
@@ -168,6 +174,7 @@
alloc = new SelectionOnQualifiedAllocationExpression();
alloc.sourceEnd = endPosition; //the position has been stored explicitly
+ int length;
if ((length = expressionLengthStack[expressionLengthPtr--]) != 0) {
expressionPtr -= length;
System.arraycopy(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
index 6f0b3ac..3b55772 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
@@ -1346,17 +1346,15 @@
* @throws NullPointerException if array is null
*/
public static final int hashCode(char[] array) {
- int hash = 0;
- int offset = 0;
int length = array.length;
- if (length < 16) {
- for (int i = length; i > 0; i--)
- hash = (hash * 37) + array[offset++];
+ int hash = length == 0 ? 31 : array[0];
+ if (length < 8) {
+ for (int i = length; --i > 0;)
+ hash = (hash * 31) + array[i];
} else {
- // only sample some characters
- int skip = length / 8;
- for (int i = length; i > 0; i -= skip, offset += skip)
- hash = (hash * 39) + array[offset];
+ // 8 characters is enough to compute a decent hash code, don't waste time examining every character
+ for (int i = length - 1, last = i > 16 ? i - 16 : 0; i > last; i -= 2)
+ hash = (hash * 31) + array[i];
}
return hash & 0x7FFFFFFF;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index c12ee08..8b04d09 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -521,8 +521,8 @@
int InvalidDigit = Syntax + Internal + 262;
/** @since 3.1 */
int InvalidLowSurrogate = Syntax + Internal + 263;
+ /** @since 3.1 */
int InvalidHighSurrogate = Syntax + Internal + 264;
-
// type related problems
/** @since 3.1 */
@@ -699,7 +699,7 @@
int IncompatibleReturnTypeForNonInheritedInterfaceMethod = MethodRelated + 413;
/** @since 2.1 */
int IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod = MethodRelated + 414;
- /** @since 3.0 */
+ /** @since 3.1 */
int IllegalVararg = MethodRelated + 415;
// code snippet support
@@ -762,9 +762,9 @@
/** @since 3.0 */
int JavadocInvalidThrowsClassName = Javadoc + Internal + 481;
/** @since 3.0 */
- int JavadocMissingReference = Javadoc + Internal + 482;
+ int JavadocMissingSeeReference = Javadoc + Internal + 482;
/** @since 3.0 */
- int JavadocInvalidReference = Javadoc + Internal + 483;
+ int JavadocInvalidSeeReference = Javadoc + Internal + 483;
/** @since 3.0 */
int JavadocInvalidSeeHref = Javadoc + Internal + 484;
/** @since 3.0 */
@@ -836,21 +836,21 @@
/** @since 3.0 */
int JavadocUnterminatedInlineTag = Javadoc + Internal + 512;
/** @since 3.0 */
- int JavadocMissingHashCharacter = Javadoc + Internal + 513;
+ int JavadocMalformedSeeReference = Javadoc + Internal + 513;
/** @since 3.0 */
- int JavadocMalformedSeeReference = Javadoc + Internal + 514;
- /** @since 3.0 */
- int JavadocEmptyReturnTag = Javadoc + Internal + 515;
+ int JavadocMessagePrefix = Internal + 514;
/** @since 3.1 */
- int JavadocInvalidValueReference = Javadoc + Internal + 516;
+ int JavadocMissingHashCharacter = Javadoc + Internal + 515;
/** @since 3.1 */
- int JavadocUnexpectedText = Javadoc + Internal + 517;
+ int JavadocEmptyReturnTag = Javadoc + Internal + 516;
/** @since 3.1 */
- int JavadocInvalidParamTagName = Javadoc + Internal + 518;
+ int JavadocInvalidValueReference = Javadoc + Internal + 517;
+ /** @since 3.1 */
+ int JavadocUnexpectedText = Javadoc + Internal + 518;
+ /** @since 3.1 */
+ int JavadocInvalidParamTagName = Javadoc + Internal + 519;
/** @since 3.1 */
int JavadocInvalidParamTagTypeParameter = Javadoc + Internal + 469;
- /** @since 3.0 */
- int JavadocMessagePrefix = Internal + 519;
/**
* Generics
@@ -860,7 +860,7 @@
/** @since 3.1 */
int IllegalTypeVariableSuperReference = Internal + 521;
/** @since 3.1 */
- int TypeVariableReferenceFromStaticContext = Internal + 522;
+ int NonStaticTypeFromStaticInvocation = Internal + 522;
/** @since 3.1 */
int ObjectCannotBeGeneric = Internal + 523;
/** @since 3.1 */
@@ -1053,6 +1053,8 @@
int MethodMissingDeprecatedAnnotation = Internal + 629;
/** @since 3.1 */
int TypeMissingDeprecatedAnnotation = Internal + 630;
+ /** @since 3.1 */
+ int UnhandledWarningToken = Internal + 631;
/**
* Corrupted binaries
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 168b33d..523d309 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -356,7 +356,7 @@
header[headerOffset++] = (byte) (0xCAFEBABEL >> 8);
header[headerOffset++] = (byte) (0xCAFEBABEL >> 0);
- final CompilerOptions options = aType.scope.environment().options;
+ final CompilerOptions options = aType.scope.compilerOptions();
this.targetJDK = options.targetJDK;
header[headerOffset++] = (byte) (this.targetJDK >> 8); // minor high
header[headerOffset++] = (byte) (this.targetJDK >> 0); // minor low
@@ -603,7 +603,8 @@
attributeNumber++;
}
if (targetJDK >= ClassFileConstants.JDK1_5
- && (this.referenceBinding.isAnonymousType() || this.referenceBinding.isLocalType())) {
+ && this.referenceBinding.isNestedType()
+ && !this.referenceBinding.isMemberType()) {
// add enclosing method attribute (1.5 mode only)
if (contentsOffset + 10 >= contents.length) {
resizeContents(10);
@@ -1237,6 +1238,9 @@
// generate a method info to define <enum>#valueOf(String)
addSyntheticEnumValueOfMethod(syntheticMethod);
break;
+ case SyntheticMethodBinding.SwitchTable :
+ // generate a method info to define the switch table synthetic method
+ addSyntheticSwitchTable(syntheticMethod);
}
}
}
@@ -1250,11 +1254,12 @@
*/
public void addSyntheticConstructorAccessMethod(SyntheticMethodBinding methodBinding) {
generateMethodInfoHeader(methodBinding);
- // We know that we won't get more than 2 attribute: the code attribute + synthetic attribute
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 2;
+ int methodAttributeOffset = this.contentsOffset;
+ // this will add exception attribute, synthetic attribute, deprecated attribute,...
+ int attributeNumber = generateMethodInfoAttribute(methodBinding);
// Code attribute
int codeAttributeOffset = contentsOffset;
+ attributeNumber++; // add code attribute
generateCodeAttributeHeader();
codeStream.init(this);
codeStream.generateSyntheticBodyForConstructorAccess(methodBinding);
@@ -1266,16 +1271,9 @@
.referenceCompilationUnit()
.compilationResult
.lineSeparatorPositions);
- // add the synthetic attribute
- int syntheticAttributeNameIndex =
- constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
- contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
- contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
- // the length of a synthetic attribute is equals to 0
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
+ // update the number of attributes
+ contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+ contents[methodAttributeOffset] = (byte) attributeNumber;
}
/**
@@ -1285,13 +1283,13 @@
* @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
*/
public void addSyntheticEnumValueOfMethod(SyntheticMethodBinding methodBinding) {
-
generateMethodInfoHeader(methodBinding);
- // We know that we won't get more than 1 attribute: the code attribute
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 1;
+ int methodAttributeOffset = this.contentsOffset;
+ // this will add exception attribute, synthetic attribute, deprecated attribute,...
+ int attributeNumber = generateMethodInfoAttribute(methodBinding);
// Code attribute
int codeAttributeOffset = contentsOffset;
+ attributeNumber++; // add code attribute
generateCodeAttributeHeader();
codeStream.init(this);
codeStream.generateSyntheticBodyForEnumValueOf(methodBinding);
@@ -1303,19 +1301,35 @@
.referenceCompilationUnit()
.compilationResult
.lineSeparatorPositions);
-// // add the synthetic attribute
-// int syntheticAttributeNameIndex =
-// constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
-// contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
-// contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
-// // the length of a synthetic attribute is equals to 0
-// contents[contentsOffset++] = 0;
-// contents[contentsOffset++] = 0;
-// contents[contentsOffset++] = 0;
-// contents[contentsOffset++] = 0;
-
+ // update the number of attributes
+ contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+ contents[methodAttributeOffset] = (byte) attributeNumber;
}
+ public void addSyntheticSwitchTable(SyntheticMethodBinding methodBinding) {
+ generateMethodInfoHeader(methodBinding);
+ int methodAttributeOffset = this.contentsOffset;
+ // this will add exception attribute, synthetic attribute, deprecated attribute,...
+ int attributeNumber = generateMethodInfoAttribute(methodBinding);
+ // Code attribute
+ int codeAttributeOffset = contentsOffset;
+ attributeNumber++; // add code attribute
+ generateCodeAttributeHeader();
+ codeStream.init(this);
+ codeStream.generateSyntheticBodyForSwitchTable(methodBinding);
+ completeCodeAttributeForSyntheticMethod(
+ true,
+ methodBinding,
+ codeAttributeOffset,
+ ((SourceTypeBinding) methodBinding.declaringClass)
+ .scope
+ .referenceCompilationUnit()
+ .compilationResult
+ .lineSeparatorPositions);
+ // update the number of attributes
+ contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+ contents[methodAttributeOffset] = (byte) attributeNumber;
+ }
/**
* INTERNAL USE-ONLY
* Generate the bytes for a synthetic method that implements Enum#values() for a given enum type
@@ -1323,13 +1337,13 @@
* @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.SyntheticAccessMethodBinding
*/
public void addSyntheticEnumValuesMethod(SyntheticMethodBinding methodBinding) {
-
generateMethodInfoHeader(methodBinding);
- // We know that we won't get more than 1 attribute: the code attribute
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 1;
+ int methodAttributeOffset = this.contentsOffset;
+ // this will add exception attribute, synthetic attribute, deprecated attribute,...
+ int attributeNumber = generateMethodInfoAttribute(methodBinding);
// Code attribute
int codeAttributeOffset = contentsOffset;
+ attributeNumber++; // add code attribute
generateCodeAttributeHeader();
codeStream.init(this);
codeStream.generateSyntheticBodyForEnumValues(methodBinding);
@@ -1341,17 +1355,9 @@
.referenceCompilationUnit()
.compilationResult
.lineSeparatorPositions);
-// // add the synthetic attribute
-// int syntheticAttributeNameIndex =
-// constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
-// contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
-// contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
-// // the length of a synthetic attribute is equals to 0
-// contents[contentsOffset++] = 0;
-// contents[contentsOffset++] = 0;
-// contents[contentsOffset++] = 0;
-// contents[contentsOffset++] = 0;
-
+ // update the number of attributes
+ contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+ contents[methodAttributeOffset] = (byte) attributeNumber;
}
/**
@@ -1363,11 +1369,12 @@
*/
public void addSyntheticFieldReadAccessMethod(SyntheticMethodBinding methodBinding) {
generateMethodInfoHeader(methodBinding);
- // We know that we won't get more than 2 attribute: the code attribute + synthetic attribute
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 2;
+ int methodAttributeOffset = this.contentsOffset;
+ // this will add exception attribute, synthetic attribute, deprecated attribute,...
+ int attributeNumber = generateMethodInfoAttribute(methodBinding);
// Code attribute
int codeAttributeOffset = contentsOffset;
+ attributeNumber++; // add code attribute
generateCodeAttributeHeader();
codeStream.init(this);
codeStream.generateSyntheticBodyForFieldReadAccess(methodBinding);
@@ -1379,16 +1386,9 @@
.referenceCompilationUnit()
.compilationResult
.lineSeparatorPositions);
- // add the synthetic attribute
- int syntheticAttributeNameIndex =
- constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
- contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
- contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
- // the length of a synthetic attribute is equals to 0
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
+ // update the number of attributes
+ contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+ contents[methodAttributeOffset] = (byte) attributeNumber;
}
/**
@@ -1400,11 +1400,12 @@
*/
public void addSyntheticFieldWriteAccessMethod(SyntheticMethodBinding methodBinding) {
generateMethodInfoHeader(methodBinding);
- // We know that we won't get more than 2 attribute: the code attribute + synthetic attribute
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 2;
+ int methodAttributeOffset = this.contentsOffset;
+ // this will add exception attribute, synthetic attribute, deprecated attribute,...
+ int attributeNumber = generateMethodInfoAttribute(methodBinding);
// Code attribute
int codeAttributeOffset = contentsOffset;
+ attributeNumber++; // add code attribute
generateCodeAttributeHeader();
codeStream.init(this);
codeStream.generateSyntheticBodyForFieldWriteAccess(methodBinding);
@@ -1416,16 +1417,9 @@
.referenceCompilationUnit()
.compilationResult
.lineSeparatorPositions);
- // add the synthetic attribute
- int syntheticAttributeNameIndex =
- constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
- contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
- contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
- // the length of a synthetic attribute is equals to 0
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
+ // update the number of attributes
+ contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+ contents[methodAttributeOffset] = (byte) attributeNumber;
}
/**
@@ -1436,11 +1430,12 @@
*/
public void addSyntheticMethodAccessMethod(SyntheticMethodBinding methodBinding) {
generateMethodInfoHeader(methodBinding);
- // We know that we won't get more than 2 attribute: the code attribute + synthetic attribute
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 2;
+ int methodAttributeOffset = this.contentsOffset;
+ // this will add exception attribute, synthetic attribute, deprecated attribute,...
+ int attributeNumber = generateMethodInfoAttribute(methodBinding);
// Code attribute
int codeAttributeOffset = contentsOffset;
+ attributeNumber++; // add code attribute
generateCodeAttributeHeader();
codeStream.init(this);
codeStream.generateSyntheticBodyForMethodAccess(methodBinding);
@@ -1452,16 +1447,9 @@
.referenceCompilationUnit()
.compilationResult
.lineSeparatorPositions);
- // add the synthetic attribute
- int syntheticAttributeNameIndex =
- constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
- contents[contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
- contents[contentsOffset++] = (byte) syntheticAttributeNameIndex;
- // the length of a synthetic attribute is equals to 0
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
- contents[contentsOffset++] = 0;
+ // update the number of attributes
+ contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
+ contents[methodAttributeOffset] = (byte) attributeNumber;
}
/**
@@ -2200,6 +2188,9 @@
localContentsOffset += 2; // first we handle the linenumber attribute
if (codeStream.generateLineNumberAttributes) {
+ if (localContentsOffset + 12 >= this.contents.length) {
+ resizeContents(12);
+ }
/* Create and add the line number attribute (used for debugging)
* Build the pairs of:
* (bytecodePC lineNumber)
@@ -2575,6 +2566,32 @@
SyntheticMethodBinding binding,
int codeAttributeOffset,
int[] startLineIndexes) {
+
+ this.completeCodeAttributeForSyntheticMethod(
+ false,
+ binding,
+ codeAttributeOffset,
+ startLineIndexes);
+ }
+
+ /**
+ * INTERNAL USE-ONLY
+ * That method completes the creation of the code attribute by setting
+ * - the attribute_length
+ * - max_stack
+ * - max_locals
+ * - code_length
+ * - exception table
+ * - and debug attributes if necessary.
+ *
+ * @param binding org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
+ * @param codeAttributeOffset <CODE>int</CODE>
+ */
+ public void completeCodeAttributeForSyntheticMethod(
+ boolean hasExceptionHandlers,
+ SyntheticMethodBinding binding,
+ int codeAttributeOffset,
+ int[] startLineIndexes) {
// reinitialize the contents with the byte modified by the code stream
this.contents = codeStream.bCodeStream;
int localContentsOffset = codeStream.classFileOffset;
@@ -2596,10 +2613,60 @@
if ((localContentsOffset + 40) >= this.contents.length) {
resizeContents(40);
}
- // there is no exception table, so we need to offset by 2 the current offset and move
- // on the attribute generation
- contents[localContentsOffset++] = 0;
- contents[localContentsOffset++] = 0;
+
+ if (hasExceptionHandlers) {
+ // write the exception table
+ int exceptionHandlersNumber = codeStream.exceptionHandlersCounter;
+ ExceptionLabel[] exceptionHandlers = codeStream.exceptionHandlers;
+ int exSize = exceptionHandlersNumber * 8 + 2;
+ if (exSize + localContentsOffset >= this.contents.length) {
+ resizeContents(exSize);
+ }
+ // there is no exception table, so we need to offset by 2 the current offset and move
+ // on the attribute generation
+ this.contents[localContentsOffset++] = (byte) (exceptionHandlersNumber >> 8);
+ this.contents[localContentsOffset++] = (byte) exceptionHandlersNumber;
+ for (int i = 0, max = codeStream.exceptionHandlersIndex; i < max; i++) {
+ ExceptionLabel exceptionHandler = exceptionHandlers[i];
+ if (exceptionHandler != null) {
+ int start = exceptionHandler.start;
+ this.contents[localContentsOffset++] = (byte) (start >> 8);
+ this.contents[localContentsOffset++] = (byte) start;
+ int end = exceptionHandler.end;
+ this.contents[localContentsOffset++] = (byte) (end >> 8);
+ this.contents[localContentsOffset++] = (byte) end;
+ int handlerPC = exceptionHandler.position;
+ this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
+ this.contents[localContentsOffset++] = (byte) handlerPC;
+ if (exceptionHandler.exceptionType == null) {
+ // any exception handler
+ this.contents[localContentsOffset++] = 0;
+ this.contents[localContentsOffset++] = 0;
+ } else {
+ int nameIndex;
+ switch(exceptionHandler.exceptionType.id) {
+ case T_null :
+ /* represents ClassNotFoundException, see class literal access*/
+ nameIndex = constantPool.literalIndexForType(ConstantPool.JavaLangClassNotFoundExceptionConstantPoolName);
+ break;
+ case T_long :
+ /* represents NoSuchFieldError, see switch table generation*/
+ nameIndex = constantPool.literalIndexForType(ConstantPool.JavaLangNoSuchFieldErrorConstantPoolName);
+ break;
+ default:
+ nameIndex = constantPool.literalIndexForType(exceptionHandler.exceptionType.constantPoolName());
+ }
+ this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) nameIndex;
+ }
+ }
+ }
+ } else {
+ // there is no exception table, so we need to offset by 2 the current offset and move
+ // on the attribute generation
+ contents[localContentsOffset++] = 0;
+ contents[localContentsOffset++] = 0;
+ }
// debug attributes
int codeAttributeAttributeOffset = localContentsOffset;
int attributeNumber = 0;
@@ -2608,6 +2675,9 @@
// first we handle the linenumber attribute
if (codeStream.generateLineNumberAttributes) {
+ if (localContentsOffset + 12 >= this.contents.length) {
+ resizeContents(12);
+ }
int index = 0;
int lineNumberNameIndex =
constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
@@ -2769,7 +2839,7 @@
contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
contentsOffset = localContentsOffset;
}
-
+
/**
* INTERNAL USE-ONLY
* Complete the creation of a method info by setting up the number of attributes at the right offset.
@@ -2844,7 +2914,7 @@
final int elementNameIndex = constantPool.literalIndex(VALUE);
contents[contentsOffset++] = (byte) (elementNameIndex >> 8);
contents[contentsOffset++] = (byte) elementNameIndex;
- MethodBinding methodBinding = singleMemberAnnotation.singlePair.binding;
+ MethodBinding methodBinding = singleMemberAnnotation.memberValuePairs()[0].binding;
if (methodBinding == null) {
contentsOffset = attributeOffset;
} else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
index ed266fc..a1c163f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
@@ -30,14 +30,19 @@
* specific fields and methods which were referenced, but does contain their
* declaring types and any other types used to locate such fields or methods.
*/
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
-import org.eclipse.jdt.core.compiler.*;
+import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.env.*;
+import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-
-import java.util.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
public class CompilationResult {
@@ -47,17 +52,21 @@
public int taskCount;
public ICompilationUnit compilationUnit;
private Map problemsMap;
- private Map firstErrorsMap;
+ private Set firstErrors;
private int maxProblemPerUnit;
public char[][][] qualifiedReferences;
public char[][] simpleNameReferences;
public int lineSeparatorPositions[];
- public Hashtable compiledTypes = new Hashtable(11);
+ public Map compiledTypes = new Hashtable(11);
public int unitIndex, totalUnitsKnown;
public boolean hasBeenAccepted = false;
public char[] fileName;
public boolean hasInconsistentToplevelHierarchies = false; // record the fact some toplevel types have inconsistent hierarchies
+ public boolean hasSyntaxError = false;
+ long[] suppressWarningIrritants; // irritant for suppressed warnings
+ long[] suppressWarningScopePositions; // (start << 32) + end
+ int suppressWarningsCount;
public CompilationResult(
char[] fileName,
@@ -104,17 +113,57 @@
priority += P_STATIC;
}
} else {
- priority += P_OUTSIDE_METHOD;
+ priority += P_OUTSIDE_METHOD;
}
} else {
priority += P_OUTSIDE_METHOD;
}
- if (firstErrorsMap.containsKey(problem)){
+ if (firstErrors.contains(problem)){
priority += P_FIRST_ERROR;
}
return priority;
}
+ public void discardSuppressedWarnings() {
+
+ if (this.suppressWarningsCount == 0) return;
+ int removed = 0;
+ nextProblem: for (int i = 0, length = this.problemCount; i < length; i++) {
+ IProblem problem = this.problems[i];
+ if (!problem.isWarning())
+ continue nextProblem;
+ int start = problem.getSourceStart();
+ int end = problem.getSourceEnd();
+ int problemID = problem.getID();
+ nextSuppress: for (int j = 0, max = this.suppressWarningsCount; j < max; j++) {
+ long position = this.suppressWarningScopePositions[j];
+ int startSuppress = (int) (position >>> 32);
+ int endSuppress = (int) position;
+ if (start < startSuppress) continue nextSuppress;
+ if (end > endSuppress) continue nextSuppress;
+ if ((ProblemReporter.getIrritant(problemID) & this.suppressWarningIrritants[j]) == 0)
+ continue nextSuppress;
+ // discard suppressed warning
+ removed++;
+ problems[i] = null;
+ if (problemsMap != null) problemsMap.remove(problem);
+ continue nextProblem;
+ }
+ }
+ if (removed > 0) {
+ for (int i = 0, index = 0; i < this.problemCount; i++) {
+ IProblem problem;
+ if ((problem = this.problems[i]) != null) {
+ if (i > index) {
+ this.problems[index++] = problem;
+ } else {
+ index++;
+ }
+ }
+ }
+ this.problemCount -= removed;
+ }
+ }
public IProblem[] getAllProblems() {
IProblem[] onlyProblems = this.getProblems();
@@ -169,12 +218,8 @@
}
public ClassFile[] getClassFiles() {
- Enumeration files = compiledTypes.elements();
ClassFile[] classFiles = new ClassFile[compiledTypes.size()];
- int index = 0;
- while (files.hasMoreElements()){
- classFiles[index++] = (ClassFile)files.nextElement();
- }
+ compiledTypes.values().toArray(classFiles);
return classFiles;
}
@@ -223,6 +268,7 @@
// Re-adjust the size of the problems if necessary.
if (problems != null) {
+ discardSuppressedWarnings();
if (this.problemCount != problems.length) {
System.arraycopy(problems, 0, (problems = new IProblem[problemCount]), 0, problemCount);
@@ -276,17 +322,6 @@
return problemCount != 0;
}
- public boolean hasSyntaxError(){
-
- if (problems != null)
- for (int i = 0; i < problemCount; i++) {
- IProblem problem = problems[i];
- if ((problem.getID() & IProblem.Syntax) != 0 && problem.isError())
- return true;
- }
- return false;
- }
-
public boolean hasTasks() {
return this.taskCount != 0;
}
@@ -369,9 +404,10 @@
public void record(IProblem newProblem, ReferenceContext referenceContext) {
- if (newProblem.getID() == IProblem.Task) {
- recordTask(newProblem);
- return;
+ //new Exception("VERBOSE PROBLEM REPORTING").printStackTrace();
+ if(newProblem.getID() == IProblem.Task) {
+ recordTask(newProblem);
+ return;
}
if (problemCount == 0) {
problems = new IProblem[5];
@@ -380,11 +416,25 @@
}
problems[problemCount++] = newProblem;
if (referenceContext != null){
- if (problemsMap == null) problemsMap = new Hashtable(5);
- if (firstErrorsMap == null) firstErrorsMap = new Hashtable(5);
- if (newProblem.isError() && !referenceContext.hasErrors()) firstErrorsMap.put(newProblem, newProblem);
+ if (problemsMap == null) problemsMap = new HashMap(5);
+ if (firstErrors == null) firstErrors = new HashSet(5);
+ if (newProblem.isError() && !referenceContext.hasErrors()) firstErrors.add(newProblem);
problemsMap.put(newProblem, referenceContext);
}
+ if ((newProblem.getID() & IProblem.Syntax) != 0 && newProblem.isError())
+ this.hasSyntaxError = true;
+ }
+
+ public void recordSuppressWarnings(long irritant, int scopeStart, int scopeEnd) {
+ if (this.suppressWarningIrritants == null) {
+ this.suppressWarningIrritants = new long[3];
+ this.suppressWarningScopePositions = new long[3];
+ } else if (this.suppressWarningIrritants.length == this.suppressWarningsCount) {
+ System.arraycopy(this.suppressWarningIrritants, 0,this.suppressWarningIrritants = new long[2*this.suppressWarningsCount], 0, this.suppressWarningsCount);
+ System.arraycopy(this.suppressWarningScopePositions, 0,this.suppressWarningScopePositions = new long[2*this.suppressWarningsCount], 0, this.suppressWarningsCount);
+ }
+ this.suppressWarningIrritants[this.suppressWarningsCount] = irritant;
+ this.suppressWarningScopePositions[this.suppressWarningsCount++] = ((long)scopeStart<<32) + scopeEnd;
}
private void recordTask(IProblem newProblem) {
@@ -411,9 +461,9 @@
}
if (this.compiledTypes != null){
buffer.append("COMPILED type(s) \n"); //$NON-NLS-1$
- Enumeration typeNames = this.compiledTypes.keys();
- while (typeNames.hasMoreElements()) {
- char[] typeName = (char[]) typeNames.nextElement();
+ Iterator keys = this.compiledTypes.keySet().iterator();
+ while (keys.hasNext()) {
+ char[] typeName = (char[]) keys.next();
buffer.append("\t - ").append(typeName).append('\n'); //$NON-NLS-1$
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
index 6d9a508..c5f0d64 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
@@ -108,7 +108,7 @@
this.problemReporter =
new ProblemReporter(policy, this.options, problemFactory);
this.lookupEnvironment =
- new LookupEnvironment(this, options, problemReporter, environment);
+ new LookupEnvironment(this, this.options, this.problemReporter, environment);
initializeParser();
}
@@ -173,7 +173,7 @@
};
}
this.problemReporter = new ProblemReporter(policy, this.options, problemFactory);
- this.lookupEnvironment = new LookupEnvironment(this, options, problemReporter, environment);
+ this.lookupEnvironment = new LookupEnvironment(this, this.options, problemReporter, environment);
initializeParser();
}
@@ -181,7 +181,7 @@
* Add an additional binary type
*/
public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
- if (options.verbose) {
+ if (this.options.verbose) {
System.out.println(
Messages.bind(Messages.compilation_loadBinary, new String(binaryType.getName())));
// new Exception("TRACE BINARY").printStackTrace(System.out);
@@ -315,7 +315,7 @@
beginToCompile(sourceUnits);
// process all units (some more could be injected in the loop by the lookup environment)
- for (; i < totalUnits; i++) {
+ for (; i < this.totalUnits; i++) {
unit = unitsToProcess[i];
try {
if (options.verbose)
@@ -323,7 +323,7 @@
Messages.bind(Messages.compilation_process,
new String[] {
String.valueOf(i + 1),
- String.valueOf(totalUnits),
+ String.valueOf(this.totalUnits),
new String(unitsToProcess[i].getFileName())
}));
process(unit, i);
@@ -338,7 +338,7 @@
Messages.bind(Messages.compilation_done,
new String[] {
String.valueOf(i + 1),
- String.valueOf(totalUnits),
+ String.valueOf(this.totalUnits),
new String(unit.getFileName())
}));
}
@@ -354,12 +354,12 @@
this.reset();
}
if (options.verbose) {
- if (totalUnits > 1) {
+ if (this.totalUnits > 1) {
System.out.println(
- Messages.bind(Messages.compilation_units, String.valueOf(totalUnits)));
+ Messages.bind(Messages.compilation_units, String.valueOf(this.totalUnits)));
} else {
System.out.println(
- Messages.bind(Messages.compilation_unit, String.valueOf(totalUnits)));
+ Messages.bind(Messages.compilation_unit, String.valueOf(this.totalUnits)));
}
}
}
@@ -372,9 +372,17 @@
CompilationUnitDeclaration unit,
CompilationResult result) {
- /* find a compilation result */
- if ((unit != null)) // basing result upon the current unit if available
+ if ((result == null) && (unit != null)) {
result = unit.compilationResult; // current unit being processed ?
+ }
+ // Lookup environment may be in middle of connecting types
+ if ((result == null) && lookupEnvironment.unitBeingCompleted != null) {
+ result = lookupEnvironment.unitBeingCompleted.compilationResult;
+ }
+ // Lookup environment may be in middle of connecting types
+ if ((result == null) && lookupEnvironment.unitBeingCompleted != null) {
+ result = lookupEnvironment.unitBeingCompleted.compilationResult;
+ }
if ((result == null) && (unitsToProcess != null) && (totalUnits > 0))
result = unitsToProcess[totalUnits - 1].compilationResult;
// last unit in beginToCompile ?
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
index 1dcc37a..ade23b6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -40,7 +40,7 @@
public final static int Bit15 = 0x4000; // is unnecessary cast (expression)
public final static int Bit16 = 0x8000; // in javadoc comment (name ref, type ref, msg)
public final static int Bit17 = 0x10000; // compound assigned (reference lhs)
- public final static int Bit18 = 0x20000;
+ public final static int Bit18 = 0x20000;
public final static int Bit19 = 0x40000;
public final static int Bit20 = 0x80000;
public final static int Bit21 = 0x100000;
@@ -157,6 +157,9 @@
// for variable argument
public static final int IsVarArgs = Bit15;
+ // for array initializer
+ public static final int IsAnnotationDefaultValue = Bit1;
+
public ASTNode() {
super();
@@ -184,13 +187,13 @@
boolean isRawMemberInvocation = !method.isStatic()
&& !receiverType.isUnboundWildcard()
&& method.declaringClass.isRawType()
- && (method.hasSubstitutedParameters() || method.hasSubstitutedReturnType());
+ && method.hasSubstitutedParameters();
MethodBinding rawOriginalGenericMethod = null;
if (!isRawMemberInvocation) {
if (method instanceof ParameterizedGenericMethodBinding) {
ParameterizedGenericMethodBinding paramMethod = (ParameterizedGenericMethodBinding) method;
- if (paramMethod.isUnchecked || (paramMethod.isRaw && (method.hasSubstitutedParameters() || method.hasSubstitutedReturnType()))) {
+ if (paramMethod.isUnchecked || (paramMethod.isRaw && method.hasSubstitutedParameters())) {
rawOriginalGenericMethod = method.original();
}
}
@@ -250,7 +253,7 @@
}
if (unsafeWildcardInvocation) {
scope.problemReporter().wildcardInvocation((ASTNode)invocationSite, receiverType, method, argumentTypes);
- } else if (!method.isStatic() && !receiverType.isUnboundWildcard() && method.declaringClass.isRawType() && (method.hasSubstitutedParameters() || method.hasSubstitutedReturnType())) {
+ } else if (!method.isStatic() && !receiverType.isUnboundWildcard() && method.declaringClass.isRawType() && method.hasSubstitutedParameters()) {
scope.problemReporter().unsafeRawInvocation((ASTNode)invocationSite, method);
} else if (rawOriginalGenericMethod != null) {
scope.problemReporter().unsafeRawGenericMethodInvocation((ASTNode)invocationSite, method);
@@ -260,23 +263,20 @@
return this;
}
- /* Answer true if the field use is considered deprecated.
- * An access in the same compilation unit is allowed.
- */
public final boolean isFieldUseDeprecated(FieldBinding field, Scope scope, boolean isStrictlyAssigned) {
-
- if (!isStrictlyAssigned && field.isPrivate() && !scope.isDefinedInField(field)) {
+
+ if (!isStrictlyAssigned && (field.isPrivate() || (field.declaringClass != null && field.declaringClass.isLocalType())) && !scope.isDefinedInField(field)) {
// ignore cases where field is used from within inside itself
- field.modifiers |= AccPrivateUsed;
+ field.original().modifiers |= AccLocallyUsed;
}
-
+
if (!field.isViewedAsDeprecated()) return false;
-
+
// inside same unit - no report
if (scope.isDefinedInSameUnit(field.declaringClass)) return false;
// if context is deprecated, may avoid reporting
- if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
+ if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
return true;
}
@@ -290,9 +290,9 @@
*/
public final boolean isMethodUseDeprecated(MethodBinding method, Scope scope) {
- if (method.isPrivate() && !scope.isDefinedInMethod(method)) {
+ if ((method.isPrivate() || method.declaringClass.isLocalType()) && !scope.isDefinedInMethod(method)) {
// ignore cases where method is used from within inside itself (e.g. direct recursions)
- method.original().modifiers |= AccPrivateUsed;
+ method.original().modifiers |= AccLocallyUsed;
}
if (!method.isViewedAsDeprecated()) return false;
@@ -301,7 +301,7 @@
if (scope.isDefinedInSameUnit(method.declaringClass)) return false;
// if context is deprecated, may avoid reporting
- if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
+ if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
return true;
}
@@ -327,9 +327,9 @@
ReferenceBinding refType = (ReferenceBinding) type;
- if (refType.isPrivate() && !scope.isDefinedInType(refType)) {
+ if ((refType.isPrivate() /*|| refType.isLocalType()*/) && !scope.isDefinedInType(refType)) {
// ignore cases where type is used from within inside itself
- ((ReferenceBinding)refType.erasure()).modifiers |= AccPrivateUsed;
+ ((ReferenceBinding)refType.erasure()).modifiers |= AccLocallyUsed;
}
if (refType.hasRestrictedAccess()) {
@@ -344,7 +344,7 @@
if (scope.isDefinedInSameUnit(refType)) return false;
// if context is deprecated, may avoid reporting
- if (!scope.environment().options.reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
+ if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode && scope.isInsideDeprecatedCode()) return false;
return true;
}
@@ -434,6 +434,7 @@
Annotation annotation = annotations[i];
annotation.recipient = recipient;
annotationTypes[i] = annotation.resolveType(scope);
+
}
// check duplicate annotations
for (int i = 0; i < length; i++) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index ff98abc..836c3c8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -79,13 +79,16 @@
if (this.arguments != null) {
// by default arguments in abstract/native methods are considered to be used (no complaint is expected)
- boolean used = this.binding == null || this.binding.isAbstract() || this.binding.isNative();
-
- int length = this.arguments.length;
- for (int i = 0; i < length; i++) {
- TypeBinding argType = this.binding == null ? null : this.binding.parameters[i];
+ if (this.binding == null) {
+ for (int i = 0, length = this.arguments.length; i < length; i++) {
+ this.arguments[i].bind(this.scope, null, true);
+ }
+ return;
+ }
+ boolean used = this.binding.isAbstract() || this.binding.isNative();
+ for (int i = 0, length = this.arguments.length; i < length; i++) {
Argument argument = this.arguments[i];
- argument.bind(this.scope, argType, used);
+ argument.bind(this.scope, this.binding.parameters[i], used);
if (argument.annotations != null) {
this.binding.tagBits |= TagBits.HasParameterAnnotations;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
index a3e8027..8325d75 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
@@ -190,7 +190,7 @@
if (this.codegenBinding.isPrivate()
&& (currentScope.enclosingSourceType() != this.codegenBinding.declaringClass)) {
- if (currentScope.environment().options.isPrivateConstructorAccessChangingVisibility) {
+ if (currentScope.compilerOptions().isPrivateConstructorAccessChangingVisibility) {
this.codegenBinding.tagForClearingPrivateModifier();
// constructor will not be dumped as private, no emulation required thus
} else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
index 758660d..9efef0f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
@@ -12,6 +12,8 @@
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.*;
/**
@@ -161,6 +163,50 @@
return output;
}
+ public void recordSuppressWarnings(Scope scope, int startSuppresss, int endSuppress, boolean isSuppressingWarnings) {
+ long suppressWarningIrritants = 0;
+ MemberValuePair[] pairs = this.memberValuePairs();
+ pairLoop: for (int i = 0, length = pairs.length; i < length; i++) {
+ MemberValuePair pair = pairs[i];
+ if (CharOperation.equals(pair.name, TypeConstants.VALUE)) {
+ Expression value = pair.value;
+ if (value instanceof ArrayInitializer) {
+ ArrayInitializer initializer = (ArrayInitializer) value;
+ Expression[] inits = initializer.expressions;
+ if (inits != null) {
+ for (int j = 0, initsLength = inits.length; j < initsLength; j++) {
+ Constant cst = inits[j].constant;
+ if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
+ long irritant = CompilerOptions.warningTokenToIrritant(cst.stringValue());
+ if (irritant != 0) {
+ suppressWarningIrritants |= irritant;
+ if (~suppressWarningIrritants == 0) break pairLoop;
+ } else {
+ scope.problemReporter().unhandledWarningToken(inits[j]);
+ }
+ }
+ }
+ }
+ } else {
+ Constant cst = value.constant;
+ if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
+ long irritant = CompilerOptions.warningTokenToIrritant(cst.stringValue());
+ if (irritant != 0) {
+ suppressWarningIrritants |= irritant;
+ if (~suppressWarningIrritants == 0) break pairLoop;
+ } else {
+ scope.problemReporter().unhandledWarningToken(value);
+ }
+ }
+ }
+ break pairLoop;
+ }
+ }
+ if (isSuppressingWarnings && suppressWarningIrritants != 0) {
+ scope.referenceCompilationUnit().compilationResult.recordSuppressWarnings(suppressWarningIrritants, startSuppresss, endSuppress);
+ }
+ }
+
public TypeBinding resolveType(BlockScope scope) {
this.constant = NotAConstant;
@@ -232,6 +278,9 @@
}
// recognize standard annotations ?
long tagBits = detectStandardAnnotation(scope, annotationType, valueAttribute);
+
+ // record annotation positions in the compilation result
+ scope.referenceCompilationUnit().compilationResult.recordSuppressWarnings(CompilerOptions.NonExternalizedString, this.sourceStart, this.declarationSourceEnd);
if (this.recipient != null) {
if (tagBits != 0) {
// tag bits onto recipient
@@ -242,16 +291,38 @@
case Binding.TYPE :
case Binding.GENERIC_TYPE :
case Binding.TYPE_PARAMETER :
- ((ReferenceBinding)this.recipient).tagBits |= tagBits;
+ SourceTypeBinding sourceType = (SourceTypeBinding) this.recipient;
+ sourceType.tagBits |= tagBits;
+ if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+ TypeDeclaration typeDeclaration = sourceType.scope.referenceContext;
+ recordSuppressWarnings(scope, typeDeclaration.declarationSourceStart, typeDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
+ }
break;
case Binding.METHOD :
- ((MethodBinding)this.recipient).tagBits |= tagBits;
+ MethodBinding sourceMethod = (MethodBinding) this.recipient;
+ sourceMethod.tagBits |= tagBits;
+ if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+ sourceType = (SourceTypeBinding) sourceMethod.declaringClass;
+ AbstractMethodDeclaration methodDeclaration = sourceType.scope.referenceContext.declarationOf(sourceMethod);
+ recordSuppressWarnings(scope, methodDeclaration.declarationSourceStart, methodDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
+ }
break;
case Binding.FIELD :
- ((FieldBinding)this.recipient).tagBits |= tagBits;
+ FieldBinding sourceField = (FieldBinding) this.recipient;
+ sourceField.tagBits |= tagBits;
+ if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+ sourceType = (SourceTypeBinding) sourceField.declaringClass;
+ FieldDeclaration fieldDeclaration = sourceType.scope.referenceContext.declarationOf(sourceField);
+ recordSuppressWarnings(scope, fieldDeclaration.declarationSourceStart, fieldDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
+ }
break;
case Binding.LOCAL :
- ((LocalVariableBinding)this.recipient).tagBits |= tagBits;
+ LocalVariableBinding variable = (LocalVariableBinding) this.recipient;
+ variable.tagBits |= tagBits;
+ if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
+ LocalDeclaration localDeclaration = variable.declaration;
+ recordSuppressWarnings(scope, localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
+ }
break;
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
index 2f0e676..f9c6bcf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
@@ -100,7 +100,7 @@
TypeBinding exceptionType = this.type.resolveType(scope, true /* check bounds*/);
if (exceptionType == null) return null;
- if (exceptionType.isGenericType() || exceptionType.isParameterizedType()) {
+ if (exceptionType.isGenericType() || exceptionType.isBoundParameterizedType()) {
scope.problemReporter().invalidParameterizedExceptionType(exceptionType, this);
return null;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
index 9ac989a..0bfcf3f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
@@ -128,7 +128,7 @@
return output.append('}');
}
- public TypeBinding resolveTypeExpecting(BlockScope scope, TypeBinding expectedTb) {
+ public TypeBinding resolveTypeExpecting(BlockScope scope, TypeBinding expectedType) {
// Array initializers can only occur on the right hand side of an assignment
// expression, therefore the expected type contains the valid information
// concerning the type that must be enforced by the elements of the array initializer.
@@ -138,42 +138,44 @@
this.constant = NotAConstant;
// allow new List<?>[5]
- TypeBinding leafComponentType = expectedTb.leafComponentType();
- if (leafComponentType.isBoundParameterizedType() || leafComponentType.isGenericType() || leafComponentType.isTypeVariable()) {
- scope.problemReporter().illegalGenericArray(leafComponentType, this);
+ if ((this.bits & IsAnnotationDefaultValue) == 0) { // annotation default value need only to be commensurate JLS9.7
+ TypeBinding leafComponentType = expectedType.leafComponentType();
+ if (leafComponentType.isBoundParameterizedType() || leafComponentType.isGenericType() || leafComponentType.isTypeVariable()) {
+ scope.problemReporter().illegalGenericArray(leafComponentType, this);
+ }
}
- if (expectedTb.isArrayType()) {
- this.resolvedType = this.binding = (ArrayBinding) expectedTb;
- if (expressions == null)
- return binding;
- TypeBinding expectedElementsTb = binding.elementsType();
- if (expectedElementsTb.isBaseType()) {
- for (int i = 0, length = expressions.length; i < length; i++) {
- Expression expression = expressions[i];
- TypeBinding expressionTb =
- (expression instanceof ArrayInitializer)
- ? expression.resolveTypeExpecting(scope, expectedElementsTb)
- : expression.resolveType(scope);
- if (expressionTb == null)
- return null;
-
- // Compile-time conversion required?
- if (expectedElementsTb != expressionTb) // must call before computeConversion() and typeMismatchError()
- scope.compilationUnitScope().recordTypeConversion(expectedElementsTb, expressionTb);
- if (expression.isConstantValueOfTypeAssignableToType(expressionTb, expectedElementsTb)
- || BaseTypeBinding.isWidening(expectedElementsTb.id, expressionTb.id)
- || scope.isBoxingCompatibleWith(expressionTb, expectedElementsTb)) {
- expression.computeConversion(scope, expectedElementsTb, expressionTb);
- } else {
- scope.problemReporter().typeMismatchError(expressionTb, expectedElementsTb, expression);
- return null;
- }
- }
- } else {
- for (int i = 0, length = expressions.length; i < length; i++)
- if (expressions[i].resolveTypeExpecting(scope, expectedElementsTb) == null)
- return null;
+ if (expectedType.isArrayType()) {
+ this.resolvedType = this.binding = (ArrayBinding) expectedType;
+ if (this.expressions == null)
+ return this.binding;
+ TypeBinding elementType = this.binding.elementsType();
+ for (int i = 0, length = expressions.length; i < length; i++) {
+ Expression expression = expressions[i];
+ TypeBinding exprType = expression instanceof ArrayInitializer
+ ? expression.resolveTypeExpecting(scope, elementType)
+ : expression.resolveType(scope);
+ if (exprType == null)
+ return null;
+
+ // Compile-time conversion required?
+ if (elementType != exprType) // must call before computeConversion() and typeMismatchError()
+ scope.compilationUnitScope().recordTypeConversion(elementType, exprType);
+
+ if ((expression.isConstantValueOfTypeAssignableToType(exprType, elementType)
+ || (elementType.isBaseType() && BaseTypeBinding.isWidening(elementType.id, exprType.id)))
+ || exprType.isCompatibleWith(elementType)) {
+ expression.computeConversion(scope, elementType, exprType);
+ } else if (scope.isBoxingCompatibleWith(exprType, elementType)
+ || (exprType.isBaseType() // narrowing then boxing ?
+ && scope.compilerOptions().sourceLevel >= JDK1_5 // autoboxing
+ && !elementType.isBaseType()
+ && expression.isConstantValueOfTypeAssignableToType(exprType, scope.environment().computeBoxingType(elementType)))) {
+ expression.computeConversion(scope, elementType, exprType);
+ } else {
+ scope.problemReporter().typeMismatchError(exprType, elementType, expression);
+ return null;
+ }
}
return binding;
}
@@ -201,7 +203,7 @@
}
if (leafElementType != null) {
TypeBinding probableTb = scope.createArrayType(leafElementType, dim);
- scope.problemReporter().typeMismatchError(probableTb, expectedTb, this);
+ scope.problemReporter().typeMismatchError(probableTb, expectedType, this);
}
return null;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
index 7307b3e..74b0f1a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
@@ -175,7 +175,7 @@
implicitConversion);
codeStream.sendOperator(postIncrement.operator, this.implicitConversion & COMPILE_TYPE_MASK);
codeStream.generateImplicitConversion(
- postIncrement.assignmentImplicitConversion);
+ postIncrement.preAssignImplicitConversion);
codeStream.arrayAtPut(this.resolvedType.id, false);
}
@@ -197,7 +197,7 @@
receiver.computeConversion(scope, arrayType, arrayType);
if (arrayType.isArrayType()) {
TypeBinding elementType = ((ArrayBinding) arrayType).elementsType();
- this.resolvedType = ((this.bits & IsStrictlyAssignedMASK) == 0) ? elementType.capture() : elementType;
+ this.resolvedType = ((this.bits & IsStrictlyAssignedMASK) == 0) ? elementType.capture(scope, this.sourceEnd) : elementType;
} else {
scope.problemReporter().referenceMustBeArrayTypeAt(arrayType, this);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
index f3dba55..2ef696d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
@@ -177,7 +177,7 @@
for (int i = 0, max = methods.length; i < max; i++) {
AbstractMethodDeclaration method = methods[i];
if (method.isClinit()) {
- ((Clinit) method).setAssertionSupport(assertionSyntheticFieldBinding, currentScope.environment().options.sourceLevel < ClassFileConstants.JDK1_5);
+ ((Clinit) method).setAssertionSupport(assertionSyntheticFieldBinding, currentScope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5);
break;
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
index 75ea4b2..6ce6104 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
@@ -169,16 +169,16 @@
public TypeBinding resolveType(BlockScope scope) {
// due to syntax lhs may be only a NameReference, a FieldReference or an ArrayReference
- constant = NotAConstant;
+ this.constant = NotAConstant;
if (!(this.lhs instanceof Reference) || this.lhs.isThis()) {
scope.problemReporter().expressionShouldBeAVariable(this.lhs);
return null;
}
TypeBinding lhsType = lhs.resolveType(scope);
- expression.setExpectedType(lhsType); // needed in case of generic method invocation
+ this.expression.setExpectedType(lhsType); // needed in case of generic method invocation
if (lhsType != null)
- this.resolvedType = lhsType.capture();
- TypeBinding rhsType = expression.resolveType(scope);
+ this.resolvedType = lhsType.capture(scope, this.sourceEnd);
+ TypeBinding rhsType = this.expression.resolveType(scope);
if (lhsType == null || rhsType == null) {
return null;
}
@@ -188,17 +188,21 @@
// may require to widen the rhs expression at runtime
if (lhsType != rhsType) // must call before computeConversion() and typeMismatchError()
scope.compilationUnitScope().recordTypeConversion(lhsType, rhsType);
- if ((expression.isConstantValueOfTypeAssignableToType(rhsType, lhsType)
+ if ((this.expression.isConstantValueOfTypeAssignableToType(rhsType, lhsType)
|| (lhsType.isBaseType() && BaseTypeBinding.isWidening(lhsType.id, rhsType.id)))
|| rhsType.isCompatibleWith(lhsType)) {
- expression.computeConversion(scope, lhsType, rhsType);
+ this.expression.computeConversion(scope, lhsType, rhsType);
checkAssignment(scope, lhsType, rhsType);
return this.resolvedType;
- } else if (scope.isBoxingCompatibleWith(rhsType, lhsType)) {
- expression.computeConversion(scope, lhsType, rhsType);
+ } else if (scope.isBoxingCompatibleWith(rhsType, lhsType)
+ || (rhsType.isBaseType() // narrowing then boxing ?
+ && scope.compilerOptions().sourceLevel >= JDK1_5 // autoboxing
+ && !lhsType.isBaseType()
+ && this.expression.isConstantValueOfTypeAssignableToType(rhsType, scope.environment().computeBoxingType(lhsType)))) {
+ this.expression.computeConversion(scope, lhsType, rhsType);
return this.resolvedType;
}
- scope.problemReporter().typeMismatchError(rhsType, lhsType, expression);
+ scope.problemReporter().typeMismatchError(rhsType, lhsType, this.expression);
return lhsType;
}
/* (non-Javadoc)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
index cfb6a44..d200034 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
@@ -1682,14 +1682,13 @@
int rightTypeID = rightType.id;
// autoboxing support
- LookupEnvironment env = scope.environment();
- boolean use15specifics = env.options.sourceLevel >= JDK1_5;
+ boolean use15specifics = scope.compilerOptions().sourceLevel >= JDK1_5;
if (use15specifics) {
if (!leftType.isBaseType() && rightTypeID != T_JavaLangString && rightTypeID != T_null) {
- leftTypeID = env.computeBoxingType(leftType).id;
+ leftTypeID = scope.environment().computeBoxingType(leftType).id;
}
if (!rightType.isBaseType() && leftTypeID != T_JavaLangString && leftTypeID != T_null) {
- rightTypeID = env.computeBoxingType(rightType).id;
+ rightTypeID = scope.environment().computeBoxingType(rightType).id;
}
}
if (leftTypeID > 15
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java
index 70c6a99..7fea712 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java
@@ -20,7 +20,7 @@
public Expression constantExpression;
public CaseLabel targetLabel;
- boolean isEnumConstant;
+ public boolean isEnumConstant;
public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) {
this.constantExpression = constantExpression;
@@ -121,7 +121,7 @@
} else {
return constantExpression.constant;
}
- } else if (scope.isBoxingCompatibleWith(switchExpressionType, caseType)) {
+ } else if (scope.isBoxingCompatibleWith(caseType, switchExpressionType)) {
constantExpression.computeConversion(scope, caseType, switchExpressionType);
return constantExpression.constant;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
index c179969..24de07e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -58,7 +58,7 @@
*/
public static void checkNeedForEnclosingInstanceCast(BlockScope scope, Expression enclosingInstance, TypeBinding enclosingInstanceType, TypeBinding memberType) {
- if (scope.environment().options.getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
+ if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
TypeBinding castedExpressionType = ((CastExpression)enclosingInstance).expression.resolvedType;
if (castedExpressionType == null) return; // cannot do better
@@ -81,7 +81,7 @@
*/
public static void checkNeedForArgumentCast(BlockScope scope, int operator, int operatorSignature, Expression expression, int expressionTypeId) {
- if (scope.environment().options.getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
+ if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
// check need for left operand cast
int alternateLeftTypeId = expressionTypeId;
@@ -117,7 +117,7 @@
*/
public static void checkNeedForArgumentCasts(BlockScope scope, Expression receiver, TypeBinding receiverType, MethodBinding binding, Expression[] arguments, TypeBinding[] argumentTypes, final InvocationSite invocationSite) {
- if (scope.environment().options.getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
+ if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
int length = argumentTypes.length;
@@ -157,7 +157,7 @@
*/
public static void checkNeedForArgumentCasts(BlockScope scope, int operator, int operatorSignature, Expression left, int leftTypeId, boolean leftIsCast, Expression right, int rightTypeId, boolean rightIsCast) {
- if (scope.environment().options.getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
+ if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;
// check need for left operand cast
int alternateLeftTypeId = leftTypeId;
@@ -238,7 +238,18 @@
: scope.getMethod(receiverType, binding.selector, alternateArgumentTypes, fakeInvocationSite);
}
if (bindingIfNoCast == binding) {
- for (int i = 0, length = originalArgumentTypes.length; i < length; i++) {
+ int argumentLength = originalArgumentTypes.length;
+ if (binding.isVarargs()) {
+ int paramLength = binding.parameters.length;
+ if (paramLength == argumentLength) {
+ int varargIndex = paramLength - 1;
+ ArrayBinding varargType = (ArrayBinding) binding.parameters[varargIndex];
+ TypeBinding lastArgType = alternateArgumentTypes[varargIndex];
+ if (varargType.dimensions == lastArgType.dimensions() && varargType.leafComponentType != lastArgType.leafComponentType())
+ return;
+ }
+ }
+ for (int i = 0; i < argumentLength; i++) {
if (originalArgumentTypes[i] != alternateArgumentTypes[i]) {
scope.problemReporter().unnecessaryCast((CastExpression)arguments[i]);
}
@@ -268,7 +279,7 @@
return true;
}
}
- } else if (isNarrowing && castType.isTypeVariable()) {
+ } else if (isNarrowing && castType.leafComponentType().isTypeVariable()) {
this.bits |= UnsafeCastMask;
return true;
}
@@ -365,19 +376,19 @@
&& ((type.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) { // no extra parenthesis around type: ((A))exp
this.resolvedType = type.resolveType(scope);
- expression.setExpectedType(this.resolvedType); // needed in case of generic method invocation
+ //expression.setExpectedType(this.resolvedType); // needed in case of generic method invocation
TypeBinding expressionType = expression.resolveType(scope);
if (this.resolvedType != null && expressionType != null) {
boolean isLegal = checkCastTypesCompatibility(scope, this.resolvedType, expressionType, this.expression);
- this.expression.computeConversion(scope, this.resolvedType, expressionType);
if (isLegal) {
+ this.expression.computeConversion(scope, this.resolvedType, expressionType);
if ((this.bits & UnsafeCastMask) != 0) { // unsafe cast
scope.problemReporter().unsafeCast(this, scope);
} else if ((this.bits & (UnnecessaryCastMASK|IgnoreNeedForCastCheckMASK)) == UnnecessaryCastMASK) { // unnecessary cast
if (!isIndirectlyUsed()) // used for generic type inference or boxing ?
scope.problemReporter().unnecessaryCast(this);
}
- this.resolvedType = this.resolvedType.capture();
+ this.resolvedType = this.resolvedType.capture(scope, this.sourceEnd);
} else { // illegal cast
scope.problemReporter().typeCastError(this, this.resolvedType, expressionType);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
index c3af69f..6c706f7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
@@ -39,7 +39,7 @@
if ((!(sourceType.isInterface()
// no field generated in interface case (would'nt verify) see 1FHHEZL
|| sourceType.isBaseType()))
- && currentScope.environment().options.sourceLevel <= ClassFileConstants.JDK1_5) {
+ && currentScope.compilerOptions().sourceLevel <= ClassFileConstants.JDK1_5) {
syntheticField = sourceType.addSyntheticFieldForClassLiteral(targetType, currentScope);
}
return flowInfo;
@@ -91,12 +91,12 @@
if (targetType.id == T_void) {
boxedType = scope.environment().getType(JAVA_LANG_VOID);
if (boxedType == null) {
- boxedType = new ProblemReferenceBinding(JAVA_LANG_VOID, ProblemReasons.NotFound);
+ boxedType = new ProblemReferenceBinding(JAVA_LANG_VOID, null, ProblemReasons.NotFound);
}
} else {
boxedType = scope.boxing(targetType);
}
- this.resolvedType = scope.createParameterizedType(classType, new TypeBinding[]{ boxedType }, null/*not a member*/);
+ this.resolvedType = scope.environment().createParameterizedType(classType, new TypeBinding[]{ boxedType }, null/*not a member*/);
} else {
this.resolvedType = classType;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 363754d..4e4fde5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -36,6 +36,8 @@
public boolean isPropagatingInnerClassEmulation;
+ public Javadoc javadoc; // 1.5 addition for package-info.java
+
public CompilationUnitDeclaration(
ProblemReporter problemReporter,
CompilationResult compilationResult,
@@ -138,9 +140,9 @@
}
public CompilationResult compilationResult() {
- return compilationResult;
+ return this.compilationResult;
}
-
+
/*
* Finds the matching type amoung this compilation unit types.
* Returns null if no type with this name is found.
@@ -173,7 +175,7 @@
}
return;
}
- if (this.isPackageInfo() && this.types != null) {
+ if (this.isPackageInfo() && this.types != null && this.currentPackage.annotations != null) {
types[0].annotations = this.currentPackage.annotations;
}
try {
@@ -218,7 +220,7 @@
public boolean isPackageInfo() {
return CharOperation.equals(this.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME)
&& this.currentPackage != null
- && this.currentPackage.annotations != null;
+ && (this.currentPackage.annotations != null || this.javadoc != null);
}
public boolean hasErrors() {
@@ -277,22 +279,25 @@
public void resolve() {
int startingTypeIndex = 0;
- if (this.currentPackage != null) {
+ boolean isPackageInfo = isPackageInfo();
+ if (this.types != null && isPackageInfo) {
+ // resolve synthetic type declaration
+ final TypeDeclaration syntheticTypeDeclaration = types[0];
+ // set empty javadoc to avoid missing warning (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=95286)
+ syntheticTypeDeclaration.javadoc = new Javadoc(syntheticTypeDeclaration.declarationSourceStart, syntheticTypeDeclaration.declarationSourceStart);
+ syntheticTypeDeclaration.resolve(this.scope);
+ // resolve annotations if any
if (this.currentPackage.annotations != null) {
- if (CharOperation.equals(this.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME)) {
- if (this.types != null) {
- // resolve annotations
- final TypeDeclaration syntheticTypeDeclaration = types[0];
- syntheticTypeDeclaration.resolve(this.scope);
- resolveAnnotations(syntheticTypeDeclaration.staticInitializerScope, this.currentPackage.annotations, this.scope.fPackage);
- // set the synthetic bit
- syntheticTypeDeclaration.binding.modifiers |= AccSynthetic;
- startingTypeIndex = 1;
- }
- } else {
- scope.problemReporter().invalidFileNameForPackageAnnotations(this.currentPackage.annotations[0]);
- }
+ resolveAnnotations(syntheticTypeDeclaration.staticInitializerScope, this.currentPackage.annotations, this.scope.fPackage);
}
+ // resolve javadoc package if any
+ if (this.javadoc != null) {
+ this.javadoc.resolve(syntheticTypeDeclaration.staticInitializerScope);
+ }
+ startingTypeIndex = 1;
+ }
+ if (this.currentPackage != null && this.currentPackage.annotations != null && !isPackageInfo) {
+ scope.problemReporter().invalidFileNameForPackageAnnotations(this.currentPackage.annotations[0]);
}
try {
if (types != null) {
@@ -300,7 +305,7 @@
types[i].resolve(scope);
}
}
- if (!this.compilationResult.hasSyntaxError()) checkUnusedImports();
+ if (!this.compilationResult.hasErrors()) checkUnusedImports();
} catch (AbortCompilationUnit e) {
this.ignoreFurtherInvestigation = true;
return;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
index 5135167..f4ed739 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
@@ -17,7 +17,7 @@
public class CompoundAssignment extends Assignment implements OperatorIds {
public int operator;
- public int assignmentImplicitConversion;
+ public int preAssignImplicitConversion;
// var op exp is equivalent to var = (varType) var op exp
// assignmentImplicitConversion stores the cast needed for the assignment
@@ -47,9 +47,9 @@
// just a local variable.
int pc = codeStream.position;
- ((Reference) lhs).generateCompoundAssignment(currentScope, codeStream, expression, operator, assignmentImplicitConversion, valueRequired);
+ ((Reference) lhs).generateCompoundAssignment(currentScope, codeStream, this.expression, this.operator, this.preAssignImplicitConversion, valueRequired);
if (valueRequired) {
- codeStream.generateImplicitConversion(implicitConversion);
+ codeStream.generateImplicitConversion(this.implicitConversion);
}
codeStream.recordPositionsFrom(pc, this.sourceStart);
}
@@ -106,7 +106,7 @@
// autoboxing support
LookupEnvironment env = scope.environment();
TypeBinding lhsType = originalLhsType, expressionType = originalExpressionType;
- boolean use15specifics = scope.environment().options.sourceLevel >= JDK1_5;
+ boolean use15specifics = scope.compilerOptions().sourceLevel >= JDK1_5;
boolean unboxedLhs = false;
if (use15specifics) {
if (!lhsType.isBaseType() && expressionType.id != T_JavaLangString && expressionType.id != T_null) {
@@ -159,10 +159,9 @@
}
}
}
- this.lhs.implicitConversion = (unboxedLhs ? UNBOXING : 0) | (result >>> 12);
- if (unboxedLhs) scope.problemReporter().autoboxing(this.lhs, originalLhsType, lhsType);
+ this.lhs.computeConversion(scope, TypeBinding.wellKnownType(scope, (result >>> 16) & 0x0000F), originalLhsType);
this.expression.computeConversion(scope, TypeBinding.wellKnownType(scope, (result >>> 8) & 0x0000F), originalExpressionType);
- this.assignmentImplicitConversion = (unboxedLhs ? BOXING : 0) | (lhsID << 4) | (result & 0x0000F);
+ this.preAssignImplicitConversion = (unboxedLhs ? BOXING : 0) | (lhsID << 4) | (result & 0x0000F);
if (unboxedLhs) scope.problemReporter().autoboxing(this, lhsType, originalLhsType);
return this.resolvedType = originalLhsType;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
index 8dddb92..4c96b09 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
@@ -276,11 +276,12 @@
}
public TypeBinding resolveType(BlockScope scope) {
- // specs p.368
+ // JLS3 15.25
constant = NotAConstant;
LookupEnvironment env = scope.environment();
- boolean use15specifics = env.options.sourceLevel >= ClassFileConstants.JDK1_5;
+ boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
TypeBinding conditionType = condition.resolveTypeExpecting(scope, BooleanBinding);
+ condition.computeConversion(scope, BooleanBinding, conditionType);
if (valueIfTrue instanceof CastExpression) valueIfTrue.bits |= IgnoreNeedForCastCheckMASK; // will check later on
TypeBinding originalValueIfTrueType = valueIfTrue.resolveType(scope);
@@ -293,23 +294,41 @@
TypeBinding valueIfTrueType = originalValueIfTrueType;
TypeBinding valueIfFalseType = originalValueIfFalseType;
- if (use15specifics) {
- if (valueIfTrueType != valueIfFalseType) {
- TypeBinding unboxedIfTrueType = valueIfTrueType.isBaseType() ? valueIfTrueType : env.computeBoxingType(valueIfTrueType);
- TypeBinding unboxedIfFalseType = valueIfFalseType.isBaseType() ? valueIfFalseType : env.computeBoxingType(valueIfFalseType);
- if (unboxedIfTrueType.isNumericType() && unboxedIfFalseType.isNumericType()) {
- valueIfTrueType = unboxedIfTrueType;
- valueIfFalseType = unboxedIfFalseType;
- } else if (valueIfTrueType.isBaseType()) {
- if ((valueIfTrueType == NullBinding) == valueIfFalseType.isBaseType()) { // bool ? null : 12 --> Integer
- valueIfFalseType = env.computeBoxingType(valueIfFalseType);
+ if (use15specifics && valueIfTrueType != valueIfFalseType) {
+ if (valueIfTrueType.isBaseType()) {
+ if (valueIfFalseType.isBaseType()) {
+ // bool ? baseType : baseType
+ if (valueIfTrueType == NullBinding) { // bool ? null : 12 --> Integer
+ valueIfFalseType = env.computeBoxingType(valueIfFalseType); // boxing
+ } else if (valueIfFalseType == NullBinding) { // bool ? 12 : null --> Integer
+ valueIfTrueType = env.computeBoxingType(valueIfTrueType); // boxing
}
- } else if (valueIfFalseType.isBaseType()) {
- if ((valueIfFalseType == NullBinding) == valueIfTrueType.isBaseType()) { // bool ? 12 : null --> Integer
- valueIfTrueType = env.computeBoxingType(valueIfTrueType);
+ } else {
+ // bool ? baseType : nonBaseType
+ TypeBinding unboxedIfFalseType = valueIfFalseType.isBaseType() ? valueIfFalseType : env.computeBoxingType(valueIfFalseType);
+ if (valueIfTrueType.isNumericType() && unboxedIfFalseType.isNumericType()) {
+ valueIfFalseType = unboxedIfFalseType; // unboxing
+ } else if (valueIfTrueType != NullBinding) { // bool ? 12 : new Integer(12) --> int
+ valueIfFalseType = env.computeBoxingType(valueIfFalseType); // unboxing
}
}
- }
+ } else if (valueIfFalseType.isBaseType()) {
+ // bool ? nonBaseType : baseType
+ TypeBinding unboxedIfTrueType = valueIfTrueType.isBaseType() ? valueIfTrueType : env.computeBoxingType(valueIfTrueType);
+ if (unboxedIfTrueType.isNumericType() && valueIfFalseType.isNumericType()) {
+ valueIfTrueType = unboxedIfTrueType; // unboxing
+ } else if (valueIfFalseType != NullBinding) { // bool ? new Integer(12) : 12 --> int
+ valueIfTrueType = env.computeBoxingType(valueIfTrueType); // unboxing
+ }
+ } else {
+ // bool ? nonBaseType : nonBaseType
+ TypeBinding unboxedIfTrueType = env.computeBoxingType(valueIfTrueType);
+ TypeBinding unboxedIfFalseType = env.computeBoxingType(valueIfFalseType);
+ if (unboxedIfTrueType.isNumericType() && unboxedIfFalseType.isNumericType()) {
+ valueIfTrueType = unboxedIfTrueType;
+ valueIfFalseType = unboxedIfFalseType;
+ }
+ }
}
// Propagate the constant value from the valueIfTrue and valueIFFalse expression if it is possible
Constant condConstant, trueConstant, falseConstant;
@@ -394,31 +413,46 @@
return this.resolvedType = DoubleBinding;
}
// Type references (null null is already tested)
- if ((valueIfTrueType.isBaseType() && valueIfTrueType != NullBinding)
- || (valueIfFalseType.isBaseType() && valueIfFalseType != NullBinding)) {
- scope.problemReporter().conditionalArgumentsIncompatibleTypes(
- this,
- valueIfTrueType,
- valueIfFalseType);
- return null;
+ if (valueIfTrueType.isBaseType() && valueIfTrueType != NullBinding) {
+ if (use15specifics) {
+ valueIfTrueType = env.computeBoxingType(valueIfTrueType);
+ } else {
+ scope.problemReporter().conditionalArgumentsIncompatibleTypes(this, valueIfTrueType, valueIfFalseType);
+ return null;
+ }
+ } else if (valueIfFalseType.isBaseType() && valueIfFalseType != NullBinding) {
+ if (use15specifics) {
+ valueIfFalseType = env.computeBoxingType(valueIfFalseType);
+ } else {
+ scope.problemReporter().conditionalArgumentsIncompatibleTypes(this, valueIfTrueType, valueIfFalseType);
+ return null;
+ }
}
- if (valueIfFalseType.isCompatibleWith(valueIfTrueType)) {
- valueIfTrue.computeConversion(scope, valueIfTrueType, originalValueIfTrueType);
- valueIfFalse.computeConversion(scope, valueIfTrueType, originalValueIfFalseType);
- return this.resolvedType = valueIfTrueType;
- }
- if (valueIfTrueType.isCompatibleWith(valueIfFalseType)) {
- valueIfTrue.computeConversion(scope, valueIfFalseType, originalValueIfTrueType);
- valueIfFalse.computeConversion(scope, valueIfFalseType, originalValueIfFalseType);
- return this.resolvedType = valueIfFalseType;
- }
- // 1.5 addition: allow most common supertype
if (use15specifics) {
- TypeBinding commonType = scope.lowerUpperBound(new TypeBinding[] { valueIfTrueType, valueIfFalseType });
+ // >= 1.5 : LUB(operand types) must exist
+ TypeBinding commonType = null;
+ if (valueIfTrueType == NullBinding) {
+ commonType = valueIfFalseType;
+ } else if (valueIfFalseType == NullBinding) {
+ commonType = valueIfTrueType;
+ } else {
+ commonType = scope.lowerUpperBound(new TypeBinding[] { valueIfTrueType, valueIfFalseType });
+ }
if (commonType != null) {
- valueIfTrue.computeConversion(scope, commonType, valueIfTrueType);
- valueIfFalse.computeConversion(scope, commonType, valueIfFalseType);
- return this.resolvedType = commonType.capture();
+ valueIfTrue.computeConversion(scope, commonType, originalValueIfTrueType);
+ valueIfFalse.computeConversion(scope, commonType, originalValueIfFalseType);
+ return this.resolvedType = commonType.capture(scope, this.sourceEnd);
+ }
+ } else {
+ // < 1.5 : one operand must be convertible to the other
+ if (valueIfFalseType.isCompatibleWith(valueIfTrueType)) {
+ valueIfTrue.computeConversion(scope, valueIfTrueType, originalValueIfTrueType);
+ valueIfFalse.computeConversion(scope, valueIfTrueType, originalValueIfFalseType);
+ return this.resolvedType = valueIfTrueType;
+ } else if (valueIfTrueType.isCompatibleWith(valueIfFalseType)) {
+ valueIfTrue.computeConversion(scope, valueIfFalseType, originalValueIfTrueType);
+ valueIfFalse.computeConversion(scope, valueIfFalseType, originalValueIfFalseType);
+ return this.resolvedType = valueIfFalseType;
}
}
scope.problemReporter().conditionalArgumentsIncompatibleTypes(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index 7346dce..edbbb7d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -40,8 +40,8 @@
if (ignoreFurtherInvestigation)
return;
- if (this.binding != null && this.binding.isPrivate() && !this.binding.isPrivateUsed()) {
- if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError()) {
+ if (this.binding != null && !this.binding.isUsed() && (this.binding.isPrivate() || (this.binding.declaringClass.tagBits & (TagBits.IsAnonymousType|TagBits.IsLocalType)) == TagBits.IsLocalType)) {
+ if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
scope.problemReporter().unusedPrivateConstructor(this);
}
}
@@ -268,7 +268,7 @@
boolean needFieldInitializations = constructorCall == null || constructorCall.accessMode != ExplicitConstructorCall.This;
// post 1.4 source level, synthetic initializations occur prior to explicit constructor call
- boolean preInitSyntheticFields = scope.environment().options.targetJDK >= ClassFileConstants.JDK1_4;
+ boolean preInitSyntheticFields = scope.compilerOptions().targetJDK >= ClassFileConstants.JDK1_4;
if (needFieldInitializations && preInitSyntheticFields){
generateSyntheticFieldInitializationsIfNecessary(scope, codeStream, declaringClass);
@@ -408,12 +408,18 @@
*/
public void resolveStatements() {
- if (!CharOperation.equals(scope.enclosingSourceType().sourceName, selector)){
- scope.problemReporter().missingReturnType(this);
+ if (!CharOperation.equals(this.scope.enclosingSourceType().sourceName, selector)){
+ this.scope.problemReporter().missingReturnType(this);
}
+ if (this.typeParameters != null) {
+ for (int i = 0, length = this.typeParameters.length; i < length; i++) {
+ this.typeParameters[i].resolve(this.scope);
+ }
+ }
+
if (this.binding != null && this.binding.declaringClass.isAnnotationType()) {
- scope.problemReporter().annotationTypeDeclarationCannotHaveConstructor(this);
+ this.scope.problemReporter().annotationTypeDeclarationCannotHaveConstructor(this);
}
// if null ==> an error has occurs at parsing time ....
if (this.constructorCall != null) {
@@ -422,7 +428,7 @@
&& this.binding.declaringClass.id == T_JavaLangObject
&& this.constructorCall.accessMode != ExplicitConstructorCall.This) {
if (this.constructorCall.accessMode == ExplicitConstructorCall.Super) {
- scope.problemReporter().cannotUseSuperInJavaLangObject(this.constructorCall);
+ this.scope.problemReporter().cannotUseSuperInJavaLangObject(this.constructorCall);
}
this.constructorCall = null;
} else {
@@ -430,7 +436,7 @@
}
}
if ((modifiers & AccSemicolonBody) != 0) {
- scope.problemReporter().methodNeedBody(this);
+ this.scope.problemReporter().methodNeedBody(this);
}
super.resolveStatements();
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java
index 9414844..ba03a7e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java
@@ -32,7 +32,7 @@
public boolean complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, boolean didAlreadyComplain) {
// before 1.4, empty statements are tolerated anywhere
- if (scope.environment().options.complianceLevel < ClassFileConstants.JDK1_4) {
+ if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_4) {
return false;
}
return super.complainIfUnreachable(flowInfo, scope, didAlreadyComplain);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
index 4f1cea4..834d3c3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
@@ -420,17 +420,16 @@
}
// autoboxing support
- LookupEnvironment env = scope.environment();
- boolean use15specifics = env.options.sourceLevel >= JDK1_5;
+ boolean use15specifics = scope.compilerOptions().sourceLevel >= JDK1_5;
TypeBinding leftType = originalLeftType, rightType = originalRightType;
if (use15specifics) {
if (leftType != NullBinding && leftType.isBaseType()) {
if (!rightType.isBaseType()) {
- rightType = env.computeBoxingType(rightType);
+ rightType = scope.environment().computeBoxingType(rightType);
}
} else {
if (rightType != NullBinding && rightType.isBaseType()) {
- leftType = env.computeBoxingType(leftType);
+ leftType = scope.environment().computeBoxingType(leftType);
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index ac86e95..64e3789 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -201,7 +201,7 @@
// perform some emulation work in case there is some and we are inside a local type only
if (binding.isPrivate() && accessMode != This) {
- if (currentScope.environment().options.isPrivateConstructorAccessChangingVisibility) {
+ if (currentScope.compilerOptions().isPrivateConstructorAccessChangingVisibility) {
this.codegenBinding.tagForClearingPrivateModifier();
// constructor will not be dumped as private, no emulation required thus
} else {
@@ -328,8 +328,8 @@
if (isMethodUseDeprecated(binding, scope))
scope.problemReporter().deprecatedMethod(binding, this);
checkInvocationArguments(scope, null, receiverType, binding, this.arguments, argumentTypes, argsContainCast, this);
- if (binding.isPrivate()) {
- binding.original().modifiers |= AccPrivateUsed;
+ if (binding.isPrivate() || receiverType.isLocalType()) {
+ binding.original().modifiers |= AccLocallyUsed;
}
} else {
if (binding.declaringClass == null)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 85fb5bc..b379b3f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -10,7 +10,7 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
-import java.util.ArrayList;
+import java.util.*;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
@@ -23,10 +23,7 @@
public abstract class Expression extends Statement {
- public static final boolean isConstantValueRepresentable(
- Constant constant,
- int constantTypeID,
- int targetTypeID) {
+ public static final boolean isConstantValueRepresentable(Constant constant, int constantTypeID, int targetTypeID) {
//true if there is no loss of precision while casting.
// constantTypeID == constant.typeID
@@ -222,8 +219,7 @@
// identity conversion cannot be performed upfront, due to side-effects
// like constant propagation
- LookupEnvironment env = scope.environment();
- boolean use15specifics = env.options.sourceLevel >= JDK1_5;
+ boolean use15specifics = scope.compilerOptions().sourceLevel >= JDK1_5;
if (castType.isBaseType()) {
if (expressionType.isBaseType()) {
if (expressionType == castType) {
@@ -247,194 +243,239 @@
}
} else if (use15specifics
- && env.computeBoxingType(expressionType).isCompatibleWith(castType)) { // unboxing - only widening match is allowed
+ && scope.environment().computeBoxingType(expressionType).isCompatibleWith(castType)) { // unboxing - only widening match is allowed
tagAsUnnecessaryCast(scope, castType);
return true;
}
return false;
} else if (use15specifics
&& expressionType.isBaseType()
- && env.computeBoxingType(expressionType).isCompatibleWith(castType)) { // boxing - only widening match is allowed
+ && scope.environment().computeBoxingType(expressionType).isCompatibleWith(castType)) { // boxing - only widening match is allowed
tagAsUnnecessaryCast(scope, castType);
return true;
}
- //-----------cast to something which is NOT a base type--------------------------
- if (expressionType == NullBinding) {
- tagAsUnnecessaryCast(scope, castType);
- return true; //null is compatible with every thing
- }
- if (expressionType.isBaseType()) {
- return false;
- }
-
- if (expressionType.isArrayType()) {
- if (castType == expressionType) {
- tagAsUnnecessaryCast(scope, castType);
- return true; // identity conversion
- }
-
- if (castType.isArrayType()) {
- //------- (castType.isArray) expressionType.isArray -----------
- TypeBinding castElementType = ((ArrayBinding) castType).elementsType();
- TypeBinding exprElementType = ((ArrayBinding) expressionType).elementsType();
- if (exprElementType.isBaseType() || castElementType.isBaseType()) {
- // <---stop the recursion-------
- if (castElementType == exprElementType) {
- tagAsNeedCheckCast();
- return true;
- } else {
- return false;
- }
- }
- // recursively on the elements...
- return checkCastTypesCompatibility(scope, ((ArrayBinding) castType).elementsType(), exprElementType, expression);
- } else if (castType.isTypeVariable()) {
- if (expressionType instanceof ReferenceBinding) {
- ReferenceBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType);
- if (match == null) {
- checkUnsafeCast(scope, castType, expressionType, match, true);
- }
- } else {
- checkUnsafeCast(scope, castType, expressionType, null, true);
- }
- // recursively on the type variable upper bound
- return checkCastTypesCompatibility(scope, castType.erasure(), expressionType, expression);
- } else if (castType.isClass() || castType.isEnum()) {
- //------(castType.isClass) expressionType.isArray ---------------
- if (castType.id == T_JavaLangObject) {
+ switch(expressionType.kind()) {
+ case Binding.BASE_TYPE :
+ //-----------cast to something which is NOT a base type--------------------------
+ if (expressionType == NullBinding) {
tagAsUnnecessaryCast(scope, castType);
- return true;
+ return true; //null is compatible with every thing
}
- } else { //------- (castType.isInterface) expressionType.isArray -----------
- if (castType.id == T_JavaLangCloneable || castType.id == T_JavaIoSerializable) {
- tagAsNeedCheckCast();
- return true;
- }
- }
- return false;
- }
- if (expressionType.isTypeVariable() || expressionType.isWildcard()) {
- if (castType instanceof ReferenceBinding) {
- TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType);
- if (match != null) {
- tagAsUnnecessaryCast(scope, castType);
- return true;
- }
- }
- // recursively on the type variable upper bound
- return checkCastTypesCompatibility(scope, castType, expressionType.erasure(), expression);
- }
-
- if (expressionType.isClass() || expressionType.isEnum()) {
- if (castType.isArrayType()) {
- // ---- (castType.isArray) expressionType.isClass -------
- if (expressionType.id == T_JavaLangObject) { // potential runtime error
- tagAsNeedCheckCast();
- return true;
- }
- } else if (castType.isTypeVariable()) {
- TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType);
- if (match == null) {
- checkUnsafeCast(scope, castType, expressionType, match, true);
- }
- // recursively on the type variable upper bound
- return checkCastTypesCompatibility(scope, castType.erasure(), expressionType, expression);
- } else if (castType.isClass() || castType.isEnum()) { // ----- (castType.isClass) expressionType.isClass ------
- TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType.erasure());
- if (match != null) {
- if (expression != null && castType.id == T_JavaLangString) this.constant = expression.constant; // (String) cst is still a constant
- return checkUnsafeCast(scope, castType, expressionType, match, false);
- }
- match = ((ReferenceBinding)castType).findSuperTypeErasingTo((ReferenceBinding)expressionType.erasure());
- if (match != null) {
- tagAsNeedCheckCast();
- return checkUnsafeCast(scope, castType, expressionType, match, true);
- }
- } else { // ----- (castType.isInterface) expressionType.isClass -------
-
- TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType.erasure());
- if (match != null) {
- return checkUnsafeCast(scope, castType, expressionType, match, false);
- }
- // a subclass may implement the interface ==> no check at compile time
- if (!((ReferenceBinding) expressionType).isFinal()) {
- tagAsNeedCheckCast();
- match = ((ReferenceBinding)castType).findSuperTypeErasingTo((ReferenceBinding)expressionType.erasure());
- if (match != null) {
- return checkUnsafeCast(scope, castType, expressionType, match, true);
- }
- return true;
- }
- // no subclass for expressionType, thus compile-time check is valid
- }
- return false;
- }
-
- // if (expressionType.isInterface()) { cannot be anything else
- if (castType.isArrayType()) {
- // ----- (castType.isArray) expressionType.isInterface ------
- if (expressionType.id == T_JavaLangCloneable
- || expressionType.id == T_JavaIoSerializable) {// potential runtime error
- tagAsNeedCheckCast();
- return true;
- } else {
return false;
- }
- } else if (castType.isTypeVariable()) {
- TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType);
- if (match == null) {
- checkUnsafeCast(scope, castType, expressionType, match, true);
- }
- // recursively on the type variable upper bound
- return checkCastTypesCompatibility(scope, castType.erasure(), expressionType, expression);
- } else if (castType.isClass() || castType.isEnum()) { // ----- (castType.isClass) expressionType.isInterface --------
-
- if (castType.id == T_JavaLangObject) { // no runtime error
- tagAsUnnecessaryCast(scope, castType);
- return true;
- }
- if (((ReferenceBinding) castType).isFinal()) {
- // no subclass for castType, thus compile-time check is valid
- TypeBinding match = ((ReferenceBinding)castType).findSuperTypeErasingTo((ReferenceBinding)expressionType.erasure());
- if (match == null) {
- // potential runtime error
- return false;
- }
- }
- } else { // ----- (castType.isInterface) expressionType.isInterface -------
- ReferenceBinding interfaceType = (ReferenceBinding) expressionType;
- TypeBinding match = interfaceType.findSuperTypeErasingTo((ReferenceBinding)castType.erasure());
- if (match != null) {
- return checkUnsafeCast(scope, castType, interfaceType, match, false);
- }
- tagAsNeedCheckCast();
- match = ((ReferenceBinding)castType).findSuperTypeErasingTo((ReferenceBinding)interfaceType.erasure());
- if (match != null) {
- return checkUnsafeCast(scope, castType, interfaceType, match, true);
+ case Binding.ARRAY_TYPE :
+ if (castType == expressionType) {
+ tagAsUnnecessaryCast(scope, castType);
+ return true; // identity conversion
}
- if (use15specifics) {
- // a subclass may implement the interface ==> no check at compile time
- return true;
- }
- // pre1.5 semantics - no covariance allowed (even if 1.5 compliant, but 1.4 source)
- MethodBinding[] castTypeMethods = getAllInheritedMethods((ReferenceBinding) castType);
- MethodBinding[] expressionTypeMethods = getAllInheritedMethods((ReferenceBinding) expressionType);
- int exprMethodsLength = expressionTypeMethods.length;
- for (int i = 0, castMethodsLength = castTypeMethods.length; i < castMethodsLength; i++)
- for (int j = 0; j < exprMethodsLength; j++) {
- if ((castTypeMethods[i].returnType != expressionTypeMethods[j].returnType)
- && (CharOperation.equals(castTypeMethods[i].selector, expressionTypeMethods[j].selector))
- && castTypeMethods[i].areParametersEqual(expressionTypeMethods[j])) {
+ switch (castType.kind()) {
+ case Binding.ARRAY_TYPE :
+ // ( ARRAY ) ARRAY
+ TypeBinding castElementType = ((ArrayBinding) castType).elementsType();
+ TypeBinding exprElementType = ((ArrayBinding) expressionType).elementsType();
+ if (exprElementType.isBaseType() || castElementType.isBaseType()) {
+ if (castElementType == exprElementType) {
+ tagAsNeedCheckCast();
+ return true;
+ }
return false;
-
}
+ // recurse on array type elements
+ return checkCastTypesCompatibility(scope, castElementType, exprElementType, expression);
+
+ case Binding.TYPE_PARAMETER :
+ // ( TYPE_PARAMETER ) ARRAY
+ if (expressionType instanceof ReferenceBinding) {
+ ReferenceBinding match = ((ReferenceBinding)expressionType).findSuperTypeWithSameErasure(castType);
+ if (match == null) {
+ checkUnsafeCast(scope, castType, expressionType, match, true);
+ }
+ } else {
+ checkUnsafeCast(scope, castType, expressionType, null, true);
+ }
+ // recurse on the type variable upper bound
+ return checkCastTypesCompatibility(scope, ((TypeVariableBinding)castType).upperBound(), expressionType, expression);
+
+ default:
+ // ( CLASS/INTERFACE ) ARRAY
+ switch (castType.id) {
+ case T_JavaLangCloneable :
+ case T_JavaIoSerializable :
+ tagAsNeedCheckCast();
+ return true;
+ case T_JavaLangObject :
+ tagAsUnnecessaryCast(scope, castType);
+ return true;
+ default :
+ return false;
+ }
+ }
+
+ case Binding.TYPE_PARAMETER :
+ if (castType instanceof ReferenceBinding) {
+ TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeWithSameErasure(castType);
+ if (match != null) {
+ return checkUnsafeCast(scope, castType, expressionType, match, false);
+ }
+ }
+ // recursively on the type variable upper bound
+ return checkCastTypesCompatibility(scope, castType, ((TypeVariableBinding)expressionType).upperBound(), expression);
+
+ case Binding.WILDCARD_TYPE : // intersection type
+ if (castType instanceof ReferenceBinding) {
+ TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeWithSameErasure(castType);
+ if (match != null) {
+ return checkUnsafeCast(scope, castType, expressionType, match, false);
+ }
+ }
+ // recursively on the type variable upper bound
+ return checkCastTypesCompatibility(scope, castType, ((WildcardBinding)expressionType).bound, expression);
+
+ default:
+ if (expressionType.isInterface()) {
+ switch (castType.kind()) {
+ case Binding.ARRAY_TYPE :
+ // ( ARRAY ) INTERFACE
+ switch (expressionType.id) {
+ case T_JavaLangCloneable :
+ case T_JavaIoSerializable :
+ tagAsNeedCheckCast();
+ return true;
+ default :
+ return false;
+ }
+
+ case Binding.TYPE_PARAMETER :
+ // ( INTERFACE ) TYPE_PARAMETER
+ TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeWithSameErasure(castType);
+ if (match == null) {
+ checkUnsafeCast(scope, castType, expressionType, match, true);
+ }
+ // recurse on the type variable upper bound
+ return checkCastTypesCompatibility(scope, ((TypeVariableBinding)castType).upperBound(), expressionType, expression);
+
+ default :
+ if (castType.isInterface()) {
+ // ( INTERFACE ) INTERFACE
+ ReferenceBinding interfaceType = (ReferenceBinding) expressionType;
+ match = interfaceType.findSuperTypeWithSameErasure(castType);
+ if (match != null) {
+ return checkUnsafeCast(scope, castType, interfaceType, match, false);
+ }
+ tagAsNeedCheckCast();
+ match = ((ReferenceBinding)castType).findSuperTypeWithSameErasure(interfaceType);
+ if (match != null) {
+ return checkUnsafeCast(scope, castType, interfaceType, match, true);
+ }
+ if (use15specifics) {
+ // ensure there is no collision between both interfaces: i.e. I1 extends List<String>, I2 extends List<Object>
+ if (interfaceType.hasIncompatibleSuperType((ReferenceBinding)castType))
+ return false;
+ } else {
+ // pre1.5 semantics - no covariance allowed (even if 1.5 compliant, but 1.4 source)
+ MethodBinding[] castTypeMethods = getAllInheritedMethods((ReferenceBinding) castType);
+ MethodBinding[] expressionTypeMethods = getAllInheritedMethods((ReferenceBinding) expressionType);
+ int exprMethodsLength = expressionTypeMethods.length;
+ for (int i = 0, castMethodsLength = castTypeMethods.length; i < castMethodsLength; i++) {
+ for (int j = 0; j < exprMethodsLength; j++) {
+ if ((castTypeMethods[i].returnType != expressionTypeMethods[j].returnType)
+ && (CharOperation.equals(castTypeMethods[i].selector, expressionTypeMethods[j].selector))
+ && castTypeMethods[i].areParametersEqual(expressionTypeMethods[j])) {
+ return false;
+
+ }
+ }
+ }
+ }
+ return true;
+ } else {
+ // ( CLASS ) INTERFACE
+ if (castType.id == T_JavaLangObject) { // no runtime error
+ tagAsUnnecessaryCast(scope, castType);
+ return true;
+ }
+ if (((ReferenceBinding) castType).isFinal()) {
+ // no subclass for castType, thus compile-time check is valid
+ match = ((ReferenceBinding)castType).findSuperTypeWithSameErasure(expressionType);
+ if (match == null /*|| !match.isCompatibleWith(expressionType)*/) {
+ // potential runtime error
+ return false;
+ }
+ }
+ if (use15specifics) {
+ // ensure there is no collision between both interfaces: i.e. I1 extends List<String>, I2 extends List<Object>
+ if (((ReferenceBinding)castType).hasIncompatibleSuperType((ReferenceBinding) expressionType))
+ return false;
+ }
+ }
}
- return true;
+ tagAsNeedCheckCast();
+ return true;
+ } else {
+ switch (castType.kind()) {
+ case Binding.ARRAY_TYPE :
+ // ( ARRAY ) CLASS
+ if (expressionType.id == T_JavaLangObject) { // potential runtime error
+ checkUnsafeCast(scope, castType, expressionType, expressionType, true);
+ tagAsNeedCheckCast();
+ return true;
+ }
+ return false;
+
+ case Binding.TYPE_PARAMETER :
+ // ( TYPE_PARAMETER ) CLASS
+ TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeWithSameErasure(castType);
+ if (match == null) {
+ checkUnsafeCast(scope, castType, expressionType, match, true);
+ }
+ // recurse on the type variable upper bound
+ return checkCastTypesCompatibility(scope, ((TypeVariableBinding)castType).upperBound(), expressionType, expression);
+
+ default :
+ if (castType.isInterface()) {
+ // ( INTERFACE ) CLASS
+ ReferenceBinding refExprType = (ReferenceBinding) expressionType;
+ match = refExprType.findSuperTypeWithSameErasure(castType);
+ if (refExprType.isFinal()) {
+ // unless final a subclass may implement the interface ==> no check at compile time
+ if (match == null || !match.isCompatibleWith(castType)) {
+ return false;
+ }
+ return checkUnsafeCast(scope, castType, expressionType, match, false);
+ } else {
+ if (match != null) {
+ return checkUnsafeCast(scope, castType, expressionType, match, false);
+ }
+ }
+ tagAsNeedCheckCast();
+ match = ((ReferenceBinding)castType).findSuperTypeWithSameErasure(expressionType);
+ if (match != null) {
+ return checkUnsafeCast(scope, castType, expressionType, match, true);
+ }
+ if (use15specifics) {
+ // ensure there is no collision between both interfaces: i.e. I1 extends List<String>, I2 extends List<Object>
+ if (refExprType.hasIncompatibleSuperType((ReferenceBinding) castType))
+ return false;
+ }
+ return true;
+ } else {
+ // ( CLASS ) CLASS
+ match = ((ReferenceBinding)expressionType).findSuperTypeWithSameErasure(castType);
+ if (match != null) {
+ if (expression != null && castType.id == T_JavaLangString) this.constant = expression.constant; // (String) cst is still a constant
+ return checkUnsafeCast(scope, castType, expressionType, match, false);
+ }
+ match = ((ReferenceBinding)castType).findSuperTypeWithSameErasure(expressionType);
+ if (match != null) {
+ tagAsNeedCheckCast();
+ return checkUnsafeCast(scope, castType, expressionType, match, true);
+ }
+ return false;
+ }
+ }
+ }
}
- tagAsNeedCheckCast();
- return true;
}
public FlowInfo checkNullStatus(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, int nullStatus) {
@@ -483,7 +524,12 @@
if (!isNarrowing) tagAsUnnecessaryCast(scope, castType);
return true;
}
- if (match != null && (castType.isBoundParameterizedType() || castType.isGenericType() || expressionType.isBoundParameterizedType() || expressionType.isGenericType())) {
+ if (match != null && (
+ castType.isBoundParameterizedType()
+ || castType.isGenericType()
+ || expressionType.isBoundParameterizedType()
+ || expressionType.isGenericType())) {
+
if (match.isProvablyDistinctFrom(isNarrowing ? expressionType : castType, 0)) {
return false;
}
@@ -496,38 +542,41 @@
* Base types need that the widening is explicitly done by the compiler using some bytecode like i2f.
* Also check unsafe type operations.
*/
- public void computeConversion(Scope scope, TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
+ public void computeConversion(Scope scope, TypeBinding runtimeType, TypeBinding compileTimeType) {
- if (runtimeTimeType == null || compileTimeType == null)
+ if (runtimeType == null || compileTimeType == null)
return;
if (this.implicitConversion != 0) return; // already set independantly
-
+
// it is possible for a Byte to be unboxed to a byte & then converted to an int
// but it is not possible for a byte to become Byte & then assigned to an Integer,
// or to become an int before boxed into an Integer
- if (runtimeTimeType != NullBinding && runtimeTimeType.isBaseType()) {
+ if (runtimeType != NullBinding && runtimeType.isBaseType()) {
if (!compileTimeType.isBaseType()) {
TypeBinding unboxedType = scope.environment().computeBoxingType(compileTimeType);
this.implicitConversion = UNBOXING;
- scope.problemReporter().autoboxing(this, compileTimeType, runtimeTimeType);
+ scope.problemReporter().autoboxing(this, compileTimeType, runtimeType);
compileTimeType = unboxedType;
}
} else {
if (compileTimeType != NullBinding && compileTimeType.isBaseType()) {
- TypeBinding boxedType = scope.environment().computeBoxingType(runtimeTimeType);
- if (boxedType == runtimeTimeType) // Object o = 12;
+ TypeBinding boxedType = scope.environment().computeBoxingType(runtimeType);
+ if (boxedType == runtimeType) // Object o = 12;
boxedType = compileTimeType;
this.implicitConversion = BOXING | (boxedType.id << 4) + compileTimeType.id;
scope.problemReporter().autoboxing(this, compileTimeType, scope.environment().computeBoxingType(boxedType));
return;
}
}
-
- switch (runtimeTimeType.id) {
+ int compileTimeTypeID, runtimeTypeID;
+ if ((compileTimeTypeID = compileTimeType.id) == NoId) { // e.g. ? extends String ==> String (103227)
+ compileTimeTypeID = compileTimeType.erasure().id == T_JavaLangString ? T_JavaLangString : T_JavaLangObject;
+ }
+ switch (runtimeTypeID = runtimeType.id) {
case T_byte :
case T_short :
case T_char :
- this.implicitConversion |= (T_int << 4) + compileTimeType.id;
+ this.implicitConversion |= (T_int << 4) + compileTimeTypeID;
break;
case T_JavaLangString :
case T_float :
@@ -535,7 +584,7 @@
case T_double :
case T_int : //implicitConversion may result in i2i which will result in NO code gen
case T_long :
- this.implicitConversion |= (runtimeTimeType.id << 4) + compileTimeType.id;
+ this.implicitConversion |= (runtimeTypeID << 4) + compileTimeTypeID;
break;
default : // regular object ref
// if (compileTimeType.isRawType() && runtimeTimeType.isBoundParameterizedType()) {
@@ -716,7 +765,7 @@
//(this request some work d be done by the VM on signed numbers)
public boolean isConstantValueOfTypeAssignableToType(TypeBinding constantType, TypeBinding targetType) {
- if (constant == Constant.NotAConstant)
+ if (this.constant == Constant.NotAConstant)
return false;
if (constantType == targetType)
return true;
@@ -726,7 +775,7 @@
|| BaseTypeBinding.isWidening(T_int, constantType.id))
&& (BaseTypeBinding.isNarrowing(targetType.id, T_int))) {
//use current explicit conversion in order to get some new value to compare with current one
- return isConstantValueRepresentable(constant, constantType.id, targetType.id);
+ return isConstantValueRepresentable(this.constant, constantType.id, targetType.id);
}
}
return false;
@@ -782,12 +831,11 @@
}
public TypeBinding resolveType(BlockScope scope) {
- // by default... subclasses should implement a better TC if required.
-
+ // by default... subclasses should implement a better TB if required.
return null;
}
- public TypeBinding resolveType(ClassScope classScope) {
+ public TypeBinding resolveType(ClassScope scope) {
// by default... subclasses should implement a better TB if required.
return null;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
index 552abcb..9a8b1bc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
@@ -56,9 +56,11 @@
FlowContext flowContext,
FlowInfo flowInfo) {
- if (this.binding != null && this.binding.isPrivate() && !this.binding.isPrivateUsed()) {
- if (!initializationScope.referenceCompilationUnit().compilationResult.hasSyntaxError()) {
- initializationScope.problemReporter().unusedPrivateField(this);
+ if (this.binding != null && !this.binding.isUsed()) {
+ if (this.binding.isPrivate() || (this.binding.declaringClass != null && this.binding.declaringClass.isLocalType())) {
+ if (!initializationScope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
+ initializationScope.problemReporter().unusedPrivateField(this);
+ }
}
}
// cannot define static non-constant field inside nested class
@@ -67,7 +69,6 @@
&& this.binding.isStatic()
&& !this.binding.isConstantValue()
&& this.binding.declaringClass.isNestedType()
- && this.binding.declaringClass.isClass() // no need to check for enum, since implicitly static
&& !this.binding.declaringClass.isStatic()) {
initializationScope.problemReporter().unexpectedStaticModifierForField(
(SourceTypeBinding) this.binding.declaringClass,
@@ -160,8 +161,6 @@
this.hasBeenResolved = true;
- resolveAnnotations(initializationScope, this.annotations, this.binding);
-
// check if field is hiding some variable - issue is that field binding already got inserted in scope
// thus must lookup separately in super type and outer context
ClassScope classScope = initializationScope.enclosingClassScope();
@@ -202,6 +201,8 @@
initializationScope.initializedField = this.binding;
initializationScope.lastVisibleFieldID = this.binding.id;
+ resolveAnnotations(initializationScope, this.annotations, this.binding);
+
// the resolution of the initialization hasn't been done
if (this.initialization == null) {
this.binding.setConstant(Constant.NotAConstant);
@@ -229,12 +230,11 @@
if (initializationType.needsUncheckedConversion(fieldType)) {
initializationScope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, fieldType);
}
- } else if (initializationScope.environment().options.sourceLevel >= JDK1_5 // autoboxing
- && (initializationScope.isBoxingCompatibleWith(initializationType, fieldType)
- || (initializationType.isBaseType() // narrowing then boxing ?
- && initializationType != null
- && !fieldType.isBaseType()
- && initialization.isConstantValueOfTypeAssignableToType(initializationType, initializationScope.environment().computeBoxingType(fieldType))))) {
+ } else if (initializationScope.isBoxingCompatibleWith(initializationType, fieldType)
+ || (initializationType.isBaseType() // narrowing then boxing ?
+ && initializationScope.compilerOptions().sourceLevel >= JDK1_5 // autoboxing
+ && !fieldType.isBaseType()
+ && initialization.isConstantValueOfTypeAssignableToType(initializationType, initializationScope.environment().computeBoxingType(fieldType)))) {
this.initialization.computeConversion(initializationScope, fieldType, initializationType);
} else {
initializationScope.problemReporter().typeMismatchError(initializationType, fieldType, this);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
index f1157b3..f25a065 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
@@ -116,7 +116,7 @@
receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic);
if (nonStatic) receiver.checkNullStatus(currentScope, flowContext, flowInfo, FlowInfo.NON_NULL);
- if (valueRequired || currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
+ if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
}
return flowInfo;
@@ -203,7 +203,7 @@
}
} else {
receiver.generateCode(currentScope, codeStream, !isStatic);
- if (valueRequired || currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
+ if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
if (this.codegenBinding.declaringClass == null) { // array length
codeStream.arraylength();
if (valueRequired) {
@@ -283,6 +283,8 @@
codeStream.generateStringConcatenationAppend(currentScope, null, expression);
break;
default :
+ if (this.genericCast != null)
+ codeStream.checkcast(this.genericCast);
// promote the array reference to the suitable operation type
codeStream.generateImplicitConversion(implicitConversion);
// generate the increment value (will by itself be promoted to the operation value)
@@ -346,13 +348,15 @@
}
}
}
- codeStream.generateImplicitConversion(implicitConversion);
+ if (this.genericCast != null)
+ codeStream.checkcast(this.genericCast);
+ codeStream.generateImplicitConversion(this.implicitConversion);
codeStream.generateConstant(
postIncrement.expression.constant,
- implicitConversion);
+ this.implicitConversion);
codeStream.sendOperator(postIncrement.operator, this.implicitConversion & COMPILE_TYPE_MASK);
codeStream.generateImplicitConversion(
- postIncrement.assignmentImplicitConversion);
+ postIncrement.preAssignImplicitConversion);
fieldStore(codeStream, this.codegenBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], false);
}
/**
@@ -483,7 +487,7 @@
&& !this.receiverType.isArrayType()
&& this.binding.declaringClass != null // array.length
&& !this.binding.isConstantValue()) {
- CompilerOptions options = currentScope.environment().options;
+ CompilerOptions options = currentScope.compilerOptions();
if ((options.targetJDK >= ClassFileConstants.JDK1_2
&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !receiver.isImplicitThis() || !this.codegenBinding.isStatic())
&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object fields
@@ -535,7 +539,7 @@
}
TypeBinding receiverErasure = this.receiverType.erasure();
if (receiverErasure instanceof ReferenceBinding) {
- ReferenceBinding match = ((ReferenceBinding)receiverErasure).findSuperTypeErasingTo((ReferenceBinding)fieldBinding.declaringClass.erasure());
+ ReferenceBinding match = ((ReferenceBinding)receiverErasure).findSuperTypeWithSameErasure(fieldBinding.declaringClass);
if (match == null) {
this.receiverType = fieldBinding.declaringClass; // handle indirect inheritance thru variable secondary bound
}
@@ -563,7 +567,7 @@
// perform capture conversion if read access
return this.resolvedType =
(((this.bits & IsStrictlyAssignedMASK) == 0)
- ? fieldBinding.type.capture()
+ ? fieldBinding.type.capture(scope, this.sourceEnd)
: fieldBinding.type);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
index 5ca6e7d..c9a4364 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
@@ -99,7 +99,7 @@
LoopingFlowContext loopingContext;
FlowInfo actionInfo;
if (action == null
- || (action.isEmptyBlock() && currentScope.environment().options.complianceLevel <= ClassFileConstants.JDK1_3)) {
+ || (action.isEmptyBlock() && currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3)) {
if (condLoopContext != null)
condLoopContext.complainOnDeferredChecks(scope, condInfo);
if (isConditionTrue) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
index 0594781..e140c0f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
@@ -94,7 +94,7 @@
FlowInfo actionInfo = condInfo.initsWhenTrue().copy();
FlowInfo exitBranch;
if (!(action == null || (action.isEmptyBlock()
- && currentScope.environment().options.complianceLevel <= ClassFileConstants.JDK1_3))) {
+ && currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) {
if (!this.action.complainIfUnreachable(actionInfo, scope, false)) {
actionInfo = action.analyseCode(scope, loopingContext, actionInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
index 8f4c949..c9dea82 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
@@ -95,7 +95,9 @@
* @see org.eclipse.jdt.internal.compiler.ast.Expression#tagAsUnnecessaryCast(Scope,TypeBinding)
*/
public void tagAsUnnecessaryCast(Scope scope, TypeBinding castType) {
- scope.problemReporter().unnecessaryInstanceof(this, castType);
+ // null is not instanceof Type, recognize direct scenario
+ if (expression.resolvedType != NullBinding)
+ scope.problemReporter().unnecessaryInstanceof(this, castType);
}
public void traverse(ASTVisitor visitor, BlockScope scope) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
index 407c27f..f56df89 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
@@ -75,19 +75,19 @@
/*
* Resolve type javadoc while a class scope
*/
- public void resolve(ClassScope classScope) {
+ public void resolve(ClassScope scope) {
// @param tags
int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length;
for (int i = 0; i < paramTagsSize; i++) {
JavadocSingleNameReference param = this.paramReferences[i];
- classScope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
+ scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd);
}
- resolveTypeParameterTags(classScope, true);
+ resolveTypeParameterTags(scope, true);
// @return tags
if (this.returnStatement != null) {
- classScope.problemReporter().javadocUnexpectedTag(this.returnStatement.sourceStart, this.returnStatement.sourceEnd);
+ scope.problemReporter().javadocUnexpectedTag(this.returnStatement.sourceStart, this.returnStatement.sourceEnd);
}
// @throws/@exception tags
@@ -107,13 +107,13 @@
start = typeRef.sourceStart;
end = typeRef.sourceEnd;
}
- classScope.problemReporter().javadocUnexpectedTag(start, end);
+ scope.problemReporter().javadocUnexpectedTag(start, end);
}
// @see tags
int seeTagsLength = this.seeReferences == null ? 0 : this.seeReferences.length;
for (int i = 0; i < seeTagsLength; i++) {
- resolveReference(this.seeReferences[i], classScope);
+ resolveReference(this.seeReferences[i], scope);
}
}
@@ -143,12 +143,12 @@
if (messageSend.binding != null && messageSend.binding.isValidBinding()) {
if (methDecl.binding.declaringClass.isCompatibleWith(messageSend.actualReceiverType) &&
CharOperation.equals(messageSend.selector, methDecl.selector) &&
- (messageSend.binding.returnType == methDecl.binding.returnType)) {
+ (methDecl.binding.returnType.isCompatibleWith(messageSend.binding.returnType))) {
if (messageSend.arguments == null && methDecl.arguments == null) {
superRef = true;
}
else if (messageSend.arguments != null && methDecl.arguments != null) {
- superRef = methDecl.binding.areParametersEqual(messageSend.binding);
+ superRef = methDecl.binding.areParametersCompatibleWith(messageSend.binding.parameters);
}
}
}
@@ -162,7 +162,7 @@
superRef = true;
}
else if (allocationExpr.arguments != null && methDecl.arguments != null) {
- superRef = methDecl.binding.areParametersEqual(allocationExpr.binding);
+ superRef = methDecl.binding.areParametersCompatibleWith(allocationExpr.binding.parameters);
}
}
}
@@ -217,14 +217,14 @@
switch (scope.kind) {
case Scope.METHOD_SCOPE:
reference.resolveType((MethodScope)scope);
- break;
+ break;
case Scope.CLASS_SCOPE:
reference.resolveType((ClassScope)scope);
- break;
+ break;
}
// Verify field references
- boolean verifyValues = scope.environment().options.sourceLevel >= ClassFileConstants.JDK1_5;
+ boolean verifyValues = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
if (reference instanceof JavadocFieldReference) {
JavadocFieldReference fieldRef = (JavadocFieldReference) reference;
int modifiers = fieldRef.binding==null ? -1 : fieldRef.binding.modifiers;
@@ -270,6 +270,12 @@
scope.problemReporter().javadocInvalidValueReference(alloc.sourceStart, alloc.sourceEnd, modifiers);
}
}
+
+ // Verify that there's no type variable reference
+ // (javadoc does not accept them and this is not a referenced bug or requested enhancement)
+ if (reference.resolvedType != null && reference.resolvedType.isTypeVariable()) {
+ scope.problemReporter().javadocInvalidReference(reference.sourceStart, reference.sourceEnd);
+ }
}
/*
@@ -392,7 +398,6 @@
// Otherwise verify that all param tags match type parameters
} else if (typeVariables.length == typeParametersLength) {
TypeVariableBinding[] bindings = new TypeVariableBinding[paramTypeParamLength];
- int maxBindings = 0;
// Scan all @param tags
for (int i = 0; i < paramTypeParamLength; i++) {
@@ -402,14 +407,14 @@
if (paramBindind.isTypeVariable()) {
// Verify duplicated tags
boolean duplicate = false;
- for (int j = 0; j < maxBindings && !duplicate; j++) {
+ for (int j = 0; j < i && !duplicate; j++) {
if (bindings[j] == param.resolvedType) {
scope.problemReporter().javadocDuplicatedParamTag(param.token, param.sourceStart, param.sourceEnd, modifiers);
duplicate = true;
}
}
if (!duplicate) {
- bindings[maxBindings++] = (TypeVariableBinding) param.resolvedType;
+ bindings[i] = (TypeVariableBinding) param.resolvedType;
}
} else {
scope.problemReporter().javadocUndeclaredParamTagName(param.token, param.sourceStart, param.sourceEnd, modifiers);
@@ -418,18 +423,25 @@
}
// Look for undocumented type parameters
- if (reportMissing) {
- for (int i = 0; i < typeParametersLength; i++) {
- TypeParameter parameter = parameters[i];
- boolean found = false;
- for (int j = 0; j < maxBindings && !found; j++) {
- if (parameter.binding == bindings[j]) {
- found = true;
- }
+ for (int i = 0; i < typeParametersLength; i++) {
+ TypeParameter parameter = parameters[i];
+ boolean found = false;
+ for (int j = 0; j < paramTypeParamLength && !found; j++) {
+ if (parameter.binding == bindings[j]) {
+ found = true;
+ bindings[j] = null;
}
- if (!found) {
- scope.problemReporter().javadocMissingParamTag(parameter.name, parameter.sourceStart, parameter.sourceEnd, modifiers);
- }
+ }
+ if (!found && reportMissing) {
+ scope.problemReporter().javadocMissingParamTag(parameter.name, parameter.sourceStart, parameter.sourceEnd, modifiers);
+ }
+ }
+
+ // Report invalid param
+ for (int i=0; i<paramTypeParamLength; i++) {
+ if (bindings[i] != null) {
+ JavadocSingleTypeReference param = this.paramTypeParameters[i];
+ scope.problemReporter().javadocUndeclaredParamTagName(param.token, param.sourceStart, param.sourceEnd, modifiers);
}
}
}
@@ -530,9 +542,7 @@
}
// If not compatible only complain on unchecked exception
- if (!compatible &&
- !typeRef.resolvedType.isCompatibleWith(methScope.getJavaLangRuntimeException()) &&
- !typeRef.resolvedType.isCompatibleWith(methScope.getJavaLangError())) {
+ if (!compatible && !typeRef.resolvedType.isUncheckedException(false)) {
methScope.problemReporter().javadocInvalidThrowsClassName(typeRef, md.binding.modifiers);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
index a662865..245b2e5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
@@ -11,8 +11,6 @@
package org.eclipse.jdt.internal.compiler.ast;
import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
public class JavadocAllocationExpression extends AllocationExpression {
@@ -70,8 +68,9 @@
if (this.resolvedType == null) {
return null;
}
- this.resolvedType = scope.convertToRawType(this.type.resolvedType);
- this.superAccess = scope.enclosingSourceType().isCompatibleWith(this.resolvedType);
+ this.resolvedType = scope.environment().convertToRawType(this.type.resolvedType);
+ SourceTypeBinding enclosingType = scope.enclosingSourceType();
+ this.superAccess = enclosingType==null ? false : enclosingType.isCompatibleWith(this.resolvedType);
ReferenceBinding allocationType = (ReferenceBinding) this.resolvedType;
this.binding = scope.getConstructor(allocationType, argumentTypes, this);
@@ -124,27 +123,17 @@
if (isMethodUseDeprecated(this.binding, scope)) {
scope.problemReporter().javadocDeprecatedMethod(this.binding, this, scope.getDeclarationModifiers());
}
- // TODO (frederic) add support for unsafe type operation warning
return allocationType;
}
-
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#isSuperAccess()
- */
+
public boolean isSuperAccess() {
return this.superAccess;
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
- */
public TypeBinding resolveType(BlockScope scope) {
return internalResolveType(scope);
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
- */
public TypeBinding resolveType(ClassScope scope) {
return internalResolveType(scope);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java
index 0ba6dae..ea24ba9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java
@@ -13,9 +13,6 @@
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.env.IConstants;
import org.eclipse.jdt.internal.compiler.lookup.*;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-
public class JavadocArgumentExpression extends Expression {
public char[] token;
@@ -51,7 +48,7 @@
scope.problemReporter().javadocDeprecatedType(this.resolvedType, typeRef, scope.getDeclarationModifiers());
return null;
}
- return this.resolvedType = scope.convertToRawType(this.resolvedType);
+ return this.resolvedType = scope.environment().convertToRawType(this.resolvedType);
}
}
return null;
@@ -82,7 +79,7 @@
public TypeBinding resolveType(ClassScope scope) {
return internalResolveType(scope);
}
-
+
/* (non-Javadoc)
* Redefine to capture javadoc specific signatures
* @see org.eclipse.jdt.internal.compiler.ast.ASTNode#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
index d776a53..43f8e0a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
@@ -65,7 +65,8 @@
fieldBinding = closestMatch; // ignore problem if can reach target field through it
}
}
- }
+ }
+ // When there's no valid field binding, try to resolve possible method reference without parenthesis
if (!fieldBinding.isValidBinding() || !(fieldBinding instanceof FieldBinding)) {
if (this.receiverType instanceof ReferenceBinding) {
ReferenceBinding refBinding = (ReferenceBinding) this.receiverType;
@@ -75,12 +76,15 @@
} else {
switch (methodBindings.length) {
case 0:
+ // no method was found: report problem
scope.problemReporter().javadocInvalidField(this.sourceStart, this.sourceEnd, fieldBinding, this.receiverType, scope.getDeclarationModifiers());
break;
case 1:
+ // one method binding was found: store binding in specific field
this.methodBinding = methodBindings[0];
break;
default:
+ // several method binding were found: store first binding in specific field and report ambiguous error
this.methodBinding = methodBindings[0];
scope.problemReporter().javadocAmbiguousMethodReference(this.sourceStart, this.sourceEnd, fieldBinding, scope.getDeclarationModifiers());
break;
@@ -97,9 +101,6 @@
return this.resolvedType = this.binding.type;
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#isSuperAccess()
- */
public boolean isSuperAccess() {
return this.superAccess;
}
@@ -113,16 +114,10 @@
return output;
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
- */
public TypeBinding resolveType(BlockScope scope) {
return internalResolveType(scope);
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
- */
public TypeBinding resolveType(ClassScope scope) {
return internalResolveType(scope);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java
index 606e479..b173c98 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java
@@ -11,10 +11,7 @@
package org.eclipse.jdt.internal.compiler.ast;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.Scope;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.*;
public class JavadocImplicitTypeReference extends TypeReference {
@@ -56,7 +53,8 @@
}
/*
- * Resolves type on a Block or Class scope.
+ * Resolves type on a Block, Class or CompilationUnit scope.
+ * We need to modify resoling behavior to avoid raw type creation.
*/
private TypeBinding internalResolveType(Scope scope) {
// handle the error here
@@ -76,39 +74,22 @@
return this.resolvedType;
}
- /* (non-Javadoc)
- * Override super implementation to avoid raw type creation.
- * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope, boolean)
- */
public TypeBinding resolveType(BlockScope blockScope, boolean checkBounds) {
return internalResolveType(blockScope);
}
- /* (non-Javadoc)
- * Override super implementation to avoid raw type creation.
- * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.ClassScope)
- */
public TypeBinding resolveType(ClassScope classScope) {
return internalResolveType(classScope);
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
- */
public void traverse(ASTVisitor visitor, BlockScope classScope) {
// Do nothing
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
- */
public void traverse(ASTVisitor visitor, ClassScope classScope) {
// Do nothing
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.ast.Expression#printExpression(int, java.lang.StringBuffer)
- */
public StringBuffer printExpression(int indent, StringBuffer output) {
return new StringBuffer();
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
index 278a6fa..ecf97d4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
@@ -78,8 +78,9 @@
if (this.actualReceiverType == null) {
return null;
}
- this.actualReceiverType = scope.convertToRawType(this.receiver.resolvedType);
- this.superAccess = scope.enclosingSourceType().isCompatibleWith(this.actualReceiverType);
+ this.actualReceiverType = scope.environment().convertToRawType(this.receiver.resolvedType);
+ SourceTypeBinding enclosingType = scope.enclosingSourceType();
+ this.superAccess = enclosingType==null ? false : enclosingType.isCompatibleWith(this.actualReceiverType);
// base type cannot receive any message
if (this.actualReceiverType.isBaseType()) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
index 0122c16..0f4d84c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
@@ -47,7 +47,7 @@
}
/*
- *
+ * We need to modify resolving behavior to handle package references
*/
private TypeBinding internalResolveType(Scope scope, boolean checkBounds) {
// handle the error here
@@ -73,18 +73,10 @@
return resolvedType;
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope)
- * We need to override to handle package references
- */
public TypeBinding resolveType(BlockScope blockScope, boolean checkBounds) {
return internalResolveType(blockScope, checkBounds);
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.ClassScope)
- * We need to override to handle package references
- */
public TypeBinding resolveType(ClassScope classScope) {
return internalResolveType(classScope, false);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
index 8e9a9b0..48d5262 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
@@ -47,6 +47,9 @@
visitor.endVisit(this, scope);
}
+ /*
+ * We need to modify resolving behavior to handle package references
+ */
TypeBinding internalResolveType(Scope scope) {
// handle the error here
this.constant = NotAConstant;
@@ -60,6 +63,13 @@
if (binding instanceof PackageBinding) {
this.packageBinding = (PackageBinding) binding;
} else {
+ if (this.resolvedType.problemId() == ProblemReasons.NonStaticReferenceInStaticContext) {
+ ReferenceBinding closestMatch = ((ProblemReferenceBinding)this.resolvedType).closestMatch;
+ if (closestMatch != null && closestMatch.isTypeVariable()) {
+ this.resolvedType = closestMatch; // ignore problem as we want report specific javadoc one instead
+ return resolvedType;
+ }
+ }
reportInvalidType(scope);
}
return null;
@@ -80,10 +90,6 @@
return internalResolveType(blockScope);
}
- /* (non-Javadoc)
- * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.ClassScope)
- * We need to override to handle package references
- */
public TypeBinding resolveType(ClassScope classScope) {
return internalResolveType(classScope);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
index fd2032d..b97b9c2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
@@ -83,6 +83,9 @@
*/
public void generateCode(BlockScope currentScope, CodeStream codeStream) {
+ if ((bits & IsReachableMASK) == 0) {
+ return;
+ }
int pc = codeStream.position;
if (targetLabel != null) {
targetLabel.initialize(codeStream);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index 210e765..dc7d371 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -178,8 +178,6 @@
this.binding.setConstant(NotAConstant);
// allow to recursivelly target the binding....
// the correct constant is harmed if correctly computed at the end of this method
-
- resolveAnnotations(scope, this.annotations, this.binding);
}
if (variableType == null) {
@@ -209,12 +207,11 @@
if (initializationType.needsUncheckedConversion(variableType)) {
scope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, variableType);
}
- } else if (scope.environment().options.sourceLevel >= JDK1_5 // autoboxing
- && (scope.isBoxingCompatibleWith(initializationType, variableType)
- || (initializationType.isBaseType() // narrowing then boxing ?
- && initializationType != null
- && !variableType.isBaseType()
- && initialization.isConstantValueOfTypeAssignableToType(initializationType, scope.environment().computeBoxingType(variableType))))) {
+ } else if (scope.isBoxingCompatibleWith(initializationType, variableType)
+ || (initializationType.isBaseType() // narrowing then boxing ?
+ && scope.compilerOptions().sourceLevel >= JDK1_5 // autoboxing
+ && !variableType.isBaseType()
+ && initialization.isConstantValueOfTypeAssignableToType(initializationType, scope.environment().computeBoxingType(variableType)))) {
this.initialization.computeConversion(scope, variableType, initializationType);
} else {
scope.problemReporter().typeMismatchError(initializationType, variableType, this);
@@ -232,6 +229,9 @@
: NotAConstant);
}
}
+ // only resolve annotation at the end, for constant to be positionned before (96991)
+ if (this.binding != null)
+ resolveAnnotations(scope, this.annotations, this.binding);
}
public void traverse(ASTVisitor visitor, BlockScope scope) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java
index 63288c0..300b141 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java
@@ -30,50 +30,71 @@
public void computeConstant() {
//the overflow (when radix=10) is tested using the fact that
//the value should always grow during its computation
-
int length = source.length - 1; //minus one because the last char is 'l' or 'L'
long computedValue ;
- if (source[0] == '0')
- { if (length == 1) { constant = Constant.fromValue(0L); return; }
+ if (source[0] == '0') {
+ if (length == 1) {
+ constant = Constant.fromValue(0L);
+ return;
+ }
final int shift,radix;
int j ;
- if ( (source[1] == 'x') || (source[1] == 'X') )
- { shift = 4 ; j = 2; radix = 16;}
- else
- { shift = 3 ; j = 1; radix = 8;}
+ if ( (source[1] == 'x') || (source[1] == 'X') ) {
+ shift = 4 ; j = 2; radix = 16;
+ } else {
+ shift = 3 ; j = 1; radix = 8;
+ }
int nbDigit = 0;
- while (source[j]=='0')
- { j++; //jump over redondant zero
- if ( j == length)
- { //watch for 0000000000000L
+ while (source[j]=='0') {
+ j++; //jump over redondant zero
+ if ( j == length) {
+ //watch for 0000000000000L
constant = Constant.fromValue(value = 0L);
- return ;}}
+ return ;
+ }
+ }
int digitValue ;
- if ((digitValue = Character.digit(source[j++],radix)) < 0 )
- { constant = FORMAT_ERROR; return ;}
- if (digitValue >= 8) nbDigit = 4;
- else if (digitValue >= 4) nbDigit = 3;
- else if (digitValue >= 2) nbDigit = 2;
- else nbDigit = 1; //digitValue is not 0
+ if ((digitValue = Character.digit(source[j++],radix)) < 0 ) {
+ constant = FORMAT_ERROR; return ;
+ }
+ if (digitValue >= 8)
+ nbDigit = 4;
+ else if (digitValue >= 4)
+ nbDigit = 3;
+ else if (digitValue >= 2)
+ nbDigit = 2;
+ else
+ nbDigit = 1; //digitValue is not 0
computedValue = digitValue ;
- while (j<length)
- { if ((digitValue = Character.digit(source[j++],radix)) < 0 )
- { constant = FORMAT_ERROR; return ;}
- if ((nbDigit += shift) > 64) return /*constant stays null*/ ;
- computedValue = (computedValue<<shift) | digitValue ;}}
-
- else
- { //-----------case radix=10-----------------
- long previous = computedValue = 0;
- for (int i = 0 ; i < length; i++)
- { int digitValue ;
- if ((digitValue = Character.digit(source[i], 10)) < 0 ) return /*constant stays null*/ ;
+ while (j<length) {
+ if ((digitValue = Character.digit(source[j++],radix)) < 0) {
+ constant = FORMAT_ERROR; return ;
+ }
+ if ((nbDigit += shift) > 64)
+ return /*constant stays null*/ ;
+ computedValue = (computedValue<<shift) | digitValue ;
+ }
+ } else {
+ //-----------case radix=10-----------------
+ long previous = 0;
+ computedValue = 0;
+ final long limit = Long.MAX_VALUE / 10; // needed to check prior to the multiplication
+ for (int i = 0 ; i < length; i++) {
+ int digitValue ;
+ if ((digitValue = Character.digit(source[i], 10)) < 0 ) return /*constant stays null*/;
previous = computedValue;
- computedValue = 10 * computedValue + digitValue ;
- if (previous > computedValue) return /*constant stays null*/;}}
-
+ if (computedValue > limit)
+ return /*constant stays null*/;
+ computedValue *= 10;
+ if ((computedValue + digitValue) > Long.MAX_VALUE)
+ return /*constant stays null*/;
+ computedValue += digitValue;
+ if (previous > computedValue)
+ return /*constant stays null*/;
+ }
+ }
constant = Constant.fromValue(value = computedValue);
}
/**
@@ -118,7 +139,8 @@
(source[15] == '5') &&
(source[16] == '8') &&
(source[17] == '0') &&
- (source[18] == '8'));}
+ (source[18] == '8'));
+}
public TypeBinding resolveType(BlockScope scope) {
// the format may be incorrect while the scanner could detect
// such error only on painfull tests...easier and faster here
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java
index 4c943da..0106577 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java
@@ -32,6 +32,9 @@
this.sourceStart = sourceStart;
this.sourceEnd = sourceEnd;
this.value = value;
+ if (value instanceof ArrayInitializer) {
+ value.bits |= IsAnnotationDefaultValue;
+ }
}
/* (non-Javadoc)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 624b6a6..0ac05f2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -76,7 +76,7 @@
} else if (this.actualReceiverType.isArrayType()
&& runtimeTimeType.id != T_JavaLangObject
&& this.binding.parameters == NoParameters
- && scope.environment().options.complianceLevel >= JDK1_5
+ && scope.compilerOptions().complianceLevel >= JDK1_5
&& CharOperation.equals(this.binding.selector, CLONE)) {
// from 1.5 compliant mode on, array#clone() resolves to array type, but codegen to #clone()Object - thus require extra inserted cast
this.valueCast = runtimeTimeType;
@@ -204,7 +204,7 @@
// and not from Object or implicit static method call.
if (this.binding.declaringClass != this.actualReceiverType
&& !this.actualReceiverType.isArrayType()) {
- CompilerOptions options = currentScope.environment().options;
+ CompilerOptions options = currentScope.compilerOptions();
if ((options.targetJDK >= ClassFileConstants.JDK1_2
&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !receiver.isImplicitThis() || !this.codegenBinding.isStatic())
&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object methods
@@ -337,9 +337,9 @@
// record the closest match, for clients who may still need hint about possible method match
if (closestMatch != null) {
this.binding = closestMatch;
- if (closestMatch.isPrivate() && !scope.isDefinedInMethod(closestMatch)) {
+ if ((closestMatch.isPrivate() || closestMatch.declaringClass.isLocalType()) && !scope.isDefinedInMethod(closestMatch)) {
// ignore cases where method is used from within inside itself (e.g. direct recursions)
- closestMatch.original().modifiers |= AccPrivateUsed;
+ closestMatch.original().modifiers |= AccLocallyUsed;
}
}
return this.resolvedType;
@@ -353,7 +353,7 @@
// compute generic cast if necessary
TypeBinding receiverErasure = this.actualReceiverType.erasure();
if (receiverErasure instanceof ReferenceBinding) {
- ReferenceBinding match = ((ReferenceBinding)receiverErasure).findSuperTypeErasingTo((ReferenceBinding)this.binding.declaringClass.erasure());
+ ReferenceBinding match = ((ReferenceBinding)receiverErasure).findSuperTypeWithSameErasure(this.binding.declaringClass);
if (match == null) {
this.actualReceiverType = this.binding.declaringClass; // handle indirect inheritance thru variable secondary bound
}
@@ -387,18 +387,19 @@
// from 1.5 compliance on, array#clone() returns the array type (but binding still shows Object)
if (actualReceiverType.isArrayType()
&& this.binding.parameters == NoParameters
- && scope.environment().options.complianceLevel >= JDK1_5
+ && scope.compilerOptions().complianceLevel >= JDK1_5
&& CharOperation.equals(this.binding.selector, CLONE)) {
this.resolvedType = actualReceiverType;
} else {
TypeBinding returnType = this.binding.returnType;
- if (returnType != null) returnType = returnType.capture();
+ if (returnType != null) returnType = returnType.capture(scope, this.sourceEnd);
this.resolvedType = returnType;
}
return this.resolvedType;
}
public void setActualReceiverType(ReferenceBinding receiverType) {
+ if (receiverType == null) return; // error scenario only
this.actualReceiverType = receiverType;
}
/**
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
index 6fd8b8d..e27fa76 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
@@ -45,8 +45,10 @@
if (binding == null)
return;
- if (this.binding.isPrivate() && !this.binding.isPrivateUsed()) {
- if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError()) {
+ if (!this.binding.isUsed() &&
+ (this.binding.isPrivate()
+ || (((this.binding.modifiers & (AccOverriding|AccImplementing)) == 0) && this.binding.declaringClass.isLocalType()))) {
+ if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
scope.problemReporter().unusedPrivateMethod(this);
}
}
@@ -128,28 +130,35 @@
// record the return type binding
}
// check if method with constructor name
- if (CharOperation.equals(scope.enclosingSourceType().sourceName, selector)) {
- scope.problemReporter().methodWithConstructorName(this);
+ if (CharOperation.equals(this.scope.enclosingSourceType().sourceName, selector)) {
+ this.scope.problemReporter().methodWithConstructorName(this);
+ }
+
+ if (this.typeParameters != null) {
+ for (int i = 0, length = this.typeParameters.length; i < length; i++) {
+ this.typeParameters[i].resolve(this.scope);
+ }
}
// check @Override annotation
- if (this.binding != null) {
+ checkOverride: {
+ if (this.binding == null) break checkOverride;
+ if (this.scope.compilerOptions().sourceLevel < JDK1_5) break checkOverride;
int bindingModifiers = this.binding.modifiers;
- if ((this.binding.tagBits & TagBits.AnnotationOverride) != 0
- && (bindingModifiers & AccOverriding) == 0) {
- // claims to override, and doesn't actually do so
- scope.problemReporter().methodMustOverride(this);
- } else if ((this.binding.tagBits & TagBits.AnnotationOverride) == 0
- && (this.binding.declaringClass.modifiers & AccInterface) == 0
- && (bindingModifiers & (AccStatic|AccOverriding)) == AccOverriding
- && scope.environment().options.sourceLevel >= JDK1_5) {
+ boolean hasOverrideAnnotation = (this.binding.tagBits & TagBits.AnnotationOverride) != 0;
+ boolean isInterfaceMethod = this.binding.declaringClass.isInterface();
+ if (hasOverrideAnnotation) {
+ if ((bindingModifiers & AccOverriding) == 0 || isInterfaceMethod)
+ // claims to override, and doesn't actually do so
+ this.scope.problemReporter().methodMustOverride(this);
+ } else if (!isInterfaceMethod && (bindingModifiers & (AccStatic|AccOverriding)) == AccOverriding) {
// actually overrides, but did not claim to do so
- scope.problemReporter().missingOverrideAnnotation(this);
+ this.scope.problemReporter().missingOverrideAnnotation(this);
}
}
// by grammatical construction, interface methods are always abstract
- switch (scope.referenceType().kind()) {
+ switch (this.scope.referenceType().kind()) {
case IGenericType.ENUM_DECL :
if (this.selector == TypeConstants.VALUES) break;
if (this.selector == TypeConstants.VALUEOF) break;
@@ -159,11 +168,11 @@
if ((this.modifiers & AccSemicolonBody) != 0) {
if ((this.modifiers & AccNative) == 0)
if ((this.modifiers & AccAbstract) == 0)
- scope.problemReporter().methodNeedBody(this);
+ this.scope.problemReporter().methodNeedBody(this);
} else {
// the method HAS a body --> abstract native modifiers are forbiden
if (((this.modifiers & AccNative) != 0) || ((this.modifiers & AccAbstract) != 0))
- scope.problemReporter().methodNeedingNoBody(this);
+ this.scope.problemReporter().methodNeedingNoBody(this);
}
}
super.resolveStatements();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
index eb40f09..b3c4ea6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
@@ -47,6 +47,7 @@
return binding instanceof ReferenceBinding;
}
public void setActualReceiverType(ReferenceBinding receiverType) {
+ if (receiverType == null) return; // error scenario only
this.actualReceiverType = receiverType;
}
public void setDepth(int depth) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
index a2b82dc..940846c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
@@ -51,17 +51,12 @@
TypeVariableBinding[] typeVariables = currentType.typeVariables();
TypeBinding[] argTypes = parameterizedType.arguments;
if (argTypes != null && typeVariables != null) { // argTypes may be null in error cases
- for (int i = 0, argLength = typeVariables.length; i < argLength; i++)
- if (typeVariables[i].boundCheck(parameterizedType, argTypes[i]) != TypeConstants.OK)
- scope.problemReporter().typeMismatchError(argTypes[i], typeVariables[i], currentType, this.typeArguments[index][i]);
+ parameterizedType.boundCheck(scope, this.typeArguments[index]);
}
}
}
public TypeReference copyDims(int dim){
- //return a type reference copy of me with some dimensions
- //warning : the new type ref has a null binding
- this.dimensions = dim;
- return this;
+ return new ParameterizedQualifiedTypeReference(this.tokens, this.typeArguments, dim, this.sourcePositions);
}
/**
@@ -146,12 +141,17 @@
}
}
if (typeIsConsistent && currentType.isStatic() && qualifiedType != null && (qualifiedType.isParameterizedType() || qualifiedType.isGenericType())) {
- scope.problemReporter().staticMemberOfParameterizedType(this, scope.createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType));
+ scope.problemReporter().staticMemberOfParameterizedType(this, scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType));
typeIsConsistent = false;
}
// check generic and arity
TypeReference[] args = this.typeArguments[i];
if (args != null) {
+ TypeReference keep = null;
+ if (isClassScope) {
+ keep = ((ClassScope) scope).superTypeReference;
+ ((ClassScope) scope).superTypeReference = null;
+ }
int argLength = args.length;
TypeBinding[] argTypes = new TypeBinding[argLength];
boolean argHasError = false;
@@ -165,14 +165,15 @@
} else {
argTypes[j] = argType;
}
- }
+ }
if (argHasError) {
return null;
}
-// TODO (philippe) if ((this.bits & ASTNode.IsSuperType) != 0)
- if (isClassScope)
+ if (isClassScope) {
+ ((ClassScope) scope).superTypeReference = keep;
if (((ClassScope) scope).detectHierarchyCycle(currentType, this, argTypes))
return null;
+ }
TypeVariableBinding[] typeVariables = currentType.typeVariables();
if (typeVariables == NoTypeVariables) { // check generic
@@ -201,28 +202,25 @@
if (isIdentical) {
qualifiedType = (ReferenceBinding) currentType.erasure();
} else {
- ParameterizedTypeBinding parameterizedType = scope.createParameterizedType((ReferenceBinding)currentType.erasure(), argTypes, qualifiedType);
+ ParameterizedTypeBinding parameterizedType = scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), argTypes, qualifiedType);
// check argument type compatibility
if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
- for (int j = 0; j < argLength; j++)
- if (typeVariables[j].boundCheck(parameterizedType, argTypes[j]) != TypeConstants.OK)
- scope.problemReporter().typeMismatchError(argTypes[j], typeVariables[j], currentType, args[j]);
+ parameterizedType.boundCheck(scope, args);
qualifiedType = parameterizedType;
}
} else {
-// TODO (philippe) if ((this.bits & ASTNode.IsSuperType) != 0)
if (isClassScope)
if (((ClassScope) scope).detectHierarchyCycle(currentType, this, null))
return null;
if (currentType.isGenericType()) {
if (typeIsConsistent && qualifiedType != null && qualifiedType.isParameterizedType()) {
- scope.problemReporter().parameterizedMemberTypeMissingArguments(this, scope.createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType));
+ scope.problemReporter().parameterizedMemberTypeMissingArguments(this, scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType));
typeIsConsistent = false;
}
qualifiedType = scope.environment().createRawType(currentType, qualifiedType); // raw type
} else {
qualifiedType = (qualifiedType != null && qualifiedType.isParameterizedType())
- ? scope.createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType)
+ ? scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType)
: currentType;
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
index 587c70a..e06dc97 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
@@ -37,9 +37,7 @@
TypeVariableBinding[] typeVariables = currentType.typeVariables();
TypeBinding[] argTypes = parameterizedType.arguments;
if (argTypes != null && typeVariables != null) { // may be null in error cases
- for (int i = 0, argLength = typeVariables.length; i < argLength; i++)
- if (typeVariables[i].boundCheck(parameterizedType, argTypes[i]) != TypeConstants.OK)
- scope.problemReporter().typeMismatchError(argTypes[i], typeVariables[i], currentType, this.typeArguments[i]);
+ parameterizedType.boundCheck(scope, this.typeArguments);
}
}
}
@@ -47,8 +45,7 @@
* @see org.eclipse.jdt.internal.compiler.ast.TypeReference#copyDims(int)
*/
public TypeReference copyDims(int dim) {
- this.dimensions = dim;
- return this;
+ return new ParameterizedSingleTypeReference(this.token, this.typeArguments, dim, (((long)this.sourceStart)<<32) + this.sourceEnd);
}
/**
@@ -109,7 +106,7 @@
if (currentType.isStatic()
|| (enclosingType.isGenericType()
&& enclosingType.outermostEnclosingType() != scope.outerMostClassScope().referenceContext.binding)) {
- enclosingType = (ReferenceBinding) scope.convertToRawType(enclosingType);
+ enclosingType = (ReferenceBinding) scope.environment().convertToRawType(enclosingType);
}
}
} else { // resolving member type (relatively to enclosingType)
@@ -124,6 +121,11 @@
// check generic and arity
boolean isClassScope = scope.kind == Scope.CLASS_SCOPE;
+ TypeReference keep = null;
+ if (isClassScope) {
+ keep = ((ClassScope) scope).superTypeReference;
+ ((ClassScope) scope).superTypeReference = null;
+ }
ReferenceBinding currentType = (ReferenceBinding) this.resolvedType;
int argLength = this.typeArguments.length;
TypeBinding[] argTypes = new TypeBinding[argLength];
@@ -140,10 +142,11 @@
}
}
if (argHasError) return null;
-// TODO (philippe) if ((this.bits & ASTNode.IsSuperType) != 0)
- if (isClassScope)
+ if (isClassScope) {
+ ((ClassScope) scope).superTypeReference = keep;
if (((ClassScope) scope).detectHierarchyCycle(currentType, this, argTypes))
return null;
+ }
TypeVariableBinding[] typeVariables = currentType.typeVariables();
if (typeVariables == NoTypeVariables) { // check generic
@@ -159,20 +162,26 @@
}
// if generic type X<T> is referred to as parameterized X<T>, then answer itself
- boolean allEqual = true;
- for (int i = 0; allEqual && i < argLength; i++)
- allEqual = typeVariables[i] == argTypes[i];
- if (!allEqual) {
- ParameterizedTypeBinding parameterizedType = scope.createParameterizedType((ReferenceBinding)currentType.erasure(), argTypes, enclosingType);
+ boolean isIdentical = true; //this.resolvedType instanceof SourceTypeBinding;
+ if (isIdentical) {
+ for (int i = 0; i < argLength; i++) {
+ if (typeVariables[i] != argTypes[i]) {
+ isIdentical = false;
+ break;
+ }
+ }
+ }
+ if (!isIdentical) {
+ ParameterizedTypeBinding parameterizedType = scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), argTypes, enclosingType);
// check argument type compatibility
if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
- for (int i = 0; i < argLength; i++)
- if (typeVariables[i].boundCheck(parameterizedType, argTypes[i]) != TypeConstants.OK)
- scope.problemReporter().typeMismatchError(argTypes[i], typeVariables[i], currentType, this.typeArguments[i]);
+ parameterizedType.boundCheck(scope, this.typeArguments);
this.resolvedType = parameterizedType;
if (isTypeUseDeprecated(this.resolvedType, scope))
reportDeprecatedType(scope);
+ } else {
+ this.resolvedType = this.resolvedType.erasure();
}
// array type ?
if (this.dimensions > 0) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index 9e66270..fa53857 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -253,11 +253,16 @@
}
if (receiverType == null) {
hasError = true;
- } else if (((ReferenceBinding) receiverType).isFinal() && this.anonymousType != null) {
- if (!receiverType.isEnum()) {
- scope.problemReporter().anonymousClassCannotExtendFinalClass(type, receiverType);
+ } else if (((ReferenceBinding) receiverType).isFinal()) {
+ if (this.anonymousType != null) {
+ if (!receiverType.isEnum()) {
+ scope.problemReporter().anonymousClassCannotExtendFinalClass(type, receiverType);
+ hasError = true;
+ }
+ } else if (!receiverType.canBeInstantiated()) {
+ scope.problemReporter().cannotInstantiate(type, receiverType);
+ return this.resolvedType = receiverType;
}
- hasError = true;
}
// resolve type arguments (for generic constructor call)
if (this.typeArguments != null) {
@@ -290,11 +295,11 @@
if (hasError) return this.resolvedType = receiverType;
if (this.anonymousType == null) {
// qualified allocation with no anonymous type
- ReferenceBinding allocationType = (ReferenceBinding) receiverType;
if (!receiverType.canBeInstantiated()) {
scope.problemReporter().cannotInstantiate(type, receiverType);
return this.resolvedType = receiverType;
}
+ ReferenceBinding allocationType = (ReferenceBinding) receiverType;
if ((this.binding = scope.getConstructor(allocationType, argumentTypes, this)).isValidBinding()) {
if (isMethodUseDeprecated(binding, scope)) {
scope.problemReporter().deprecatedMethod(this.binding, this);
@@ -314,7 +319,7 @@
scope.compilationUnitScope().recordTypeConversion(expectedType, enclosingInstanceType);
if (enclosingInstanceType.isCompatibleWith(expectedType) || scope.isBoxingCompatibleWith(enclosingInstanceType, expectedType)) {
enclosingInstance.computeConversion(scope, expectedType, enclosingInstanceType);
- return receiverType;
+ return this.resolvedType = receiverType;
}
scope.problemReporter().typeMismatchError(enclosingInstanceType, expectedType, this.enclosingInstance);
return this.resolvedType = receiverType;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
index 2a2905a..dbfa039 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
@@ -58,7 +58,23 @@
lastFieldBinding = (FieldBinding) binding;
if (needValue) {
manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, this.actualReceiverType, 0, flowInfo);
- } // check if final blank field
+ }
+ if (this.indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
+ ReferenceBinding declaringClass = lastFieldBinding.declaringClass;
+ // check if accessing enum static field in initializer
+ if (declaringClass.isEnum()) {
+ MethodScope methodScope = currentScope.methodScope();
+ SourceTypeBinding sourceType = methodScope.enclosingSourceType();
+ if (lastFieldBinding.isStatic()
+ && (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+ && lastFieldBinding.constant() == NotAConstant
+ && !methodScope.isStatic
+ && methodScope.isInsideInitializerOrConstructor()) {
+ currentScope.problemReporter().enumStaticFieldUsedDuringInitialization(lastFieldBinding, this);
+ }
+ }
+ }
+ // check if final blank field
if (lastFieldBinding.isBlankFinal()
&& this.otherBindings != null // the last field binding is only assigned
&& currentScope.allowBlankFinalFieldAssignment(lastFieldBinding)) {
@@ -90,7 +106,7 @@
}
// all intermediate field accesses are read accesses
if (otherBindings != null) {
- boolean complyTo14 = currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4;
+ boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
for (int i = 0; i < otherBindingsCount-1; i++) {
lastFieldBinding = otherBindings[i];
needValue = !otherBindings[i+1].isStatic();
@@ -200,14 +216,27 @@
if (needValue) {
manageSyntheticAccessIfNecessary(currentScope, (FieldBinding) binding, this.actualReceiverType, 0, flowInfo);
}
- // check if reading a final blank field
- FieldBinding fieldBinding;
- if ((fieldBinding = (FieldBinding) binding).isBlankFinal()
- && (indexOfFirstFieldBinding == 1)
- // was an implicit reference to the first field binding
- && currentScope.allowBlankFinalFieldAssignment(fieldBinding)
- && (!flowInfo.isDefinitelyAssigned(fieldBinding))) {
- currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+ if (this.indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
+ FieldBinding fieldBinding = (FieldBinding) binding;
+ ReferenceBinding declaringClass = fieldBinding.declaringClass;
+ // check if accessing enum static field in initializer
+ if (declaringClass.isEnum()) {
+ MethodScope methodScope = currentScope.methodScope();
+ SourceTypeBinding sourceType = methodScope.enclosingSourceType();
+ if (fieldBinding.isStatic()
+ && (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+ && fieldBinding.constant() == NotAConstant
+ && !methodScope.isStatic
+ && methodScope.isInsideInitializerOrConstructor()) {
+ currentScope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
+ }
+ }
+ // check if reading a final blank field
+ if (fieldBinding.isBlankFinal()
+ && currentScope.allowBlankFinalFieldAssignment(fieldBinding)
+ && !flowInfo.isDefinitelyAssigned(fieldBinding)) {
+ currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
+ }
}
break;
case Binding.LOCAL : // reading a local variable
@@ -228,7 +257,7 @@
// only for first binding
}
if (otherBindings != null) {
- boolean complyTo14 = currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4;
+ boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
for (int i = 0; i < otherBindingsCount; i++) {
needValue = i < otherBindingsCount-1 ? !otherBindings[i+1].isStatic() : valueRequired;
if (needValue || complyTo14) {
@@ -255,15 +284,15 @@
* Check and/or redirect the field access to the delegate receiver if any
*/
public TypeBinding checkFieldAccess(BlockScope scope) {
- // check for forward references
FieldBinding fieldBinding = (FieldBinding) binding;
MethodScope methodScope = scope.methodScope();
- if (methodScope.enclosingSourceType() == fieldBinding.declaringClass
- && methodScope.lastVisibleFieldID >= 0
- && fieldBinding.id >= methodScope.lastVisibleFieldID) {
- if ((!fieldBinding.isStatic() || methodScope.isStatic)
- && this.indexOfFirstFieldBinding == 1)
- scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType());
+ // check for forward references
+ if (this.indexOfFirstFieldBinding == 1
+ && methodScope.enclosingSourceType() == fieldBinding.declaringClass
+ && methodScope.lastVisibleFieldID >= 0
+ && fieldBinding.id >= methodScope.lastVisibleFieldID
+ && (!fieldBinding.isStatic() || methodScope.isStatic)) {
+ scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType());
}
bits &= ~RestrictiveFlagMASK; // clear bits
bits |= Binding.FIELD;
@@ -340,7 +369,7 @@
codeStream.generateConstant(lastFieldBinding.constant(), implicitConversion);
}
} else {
- if (valueRequired || currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
+ if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
if (lastFieldBinding.declaringClass == null) { // array length
codeStream.arraylength();
if (valueRequired) {
@@ -427,6 +456,8 @@
codeStream.generateStringConcatenationAppend(currentScope, null, expression);
break;
default :
+ TypeBinding requiredGenericCast = getGenericCast(this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length);
+ if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast);
// promote the array reference to the suitable operation type
codeStream.generateImplicitConversion(implicitConversion);
// generate the increment value (will by itself be promoted to the operation value)
@@ -487,13 +518,16 @@
}
}
}
+ TypeBinding requiredGenericCast = getGenericCast(this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length);
+ if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast);
+
codeStream.generateImplicitConversion(implicitConversion);
codeStream.generateConstant(
postIncrement.expression.constant,
implicitConversion);
codeStream.sendOperator(postIncrement.operator, this.implicitConversion & COMPILE_TYPE_MASK);
codeStream.generateImplicitConversion(
- postIncrement.assignmentImplicitConversion);
+ postIncrement.preAssignImplicitConversion);
fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, false);
}
/*
@@ -507,7 +541,7 @@
boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic();
FieldBinding lastFieldBinding = null;
TypeBinding lastGenericCast = null;
- boolean complyTo14 = currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4;
+ boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
switch (bits & RestrictiveFlagMASK) {
case Binding.FIELD :
@@ -657,7 +691,7 @@
this.constant = FieldReference.getConstantFor((FieldBinding) binding, this, false, scope);
// perform capture conversion if read access
return (type != null && (this.bits & IsStrictlyAssignedMASK) == 0)
- ? type.capture()
+ ? type.capture(scope, this.sourceEnd)
: type;
}
// allocation of the fieldBindings array and its respective constants
@@ -679,7 +713,7 @@
bits &= ~DepthMASK; // flush previous depth if any
FieldBinding previousField = field;
- field = scope.getField(type.capture(), token, this);
+ field = scope.getField(type.capture(scope, (int)this.sourcePositions[index]), token, this);
int place = index - indexOfFirstFieldBinding;
otherBindings[place] = field;
otherDepths[place] = (bits & DepthMASK) >> DepthSHIFT;
@@ -689,7 +723,7 @@
TypeBinding fieldReceiverType = type;
TypeBinding receiverErasure = type.erasure();
if (receiverErasure instanceof ReferenceBinding) {
- ReferenceBinding match = ((ReferenceBinding)receiverErasure).findSuperTypeErasingTo((ReferenceBinding)field.declaringClass.erasure());
+ ReferenceBinding match = ((ReferenceBinding)receiverErasure).findSuperTypeWithSameErasure(field.declaringClass);
if (match == null) {
fieldReceiverType = field.declaringClass; // handle indirect inheritance thru variable secondary bound
}
@@ -730,7 +764,7 @@
type = (otherBindings[otherBindingsLength - 1]).type;
// perform capture conversion if read access
return (type != null && (this.bits & IsStrictlyAssignedMASK) == 0)
- ? type.capture()
+ ? type.capture(scope, this.sourceEnd)
: type;
}
public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
@@ -794,7 +828,7 @@
&& !lastReceiverType.isArrayType()
&& fieldBinding.declaringClass != null // array.length
&& !fieldBinding.isConstantValue()) {
- CompilerOptions options = currentScope.environment().options;
+ CompilerOptions options = currentScope.compilerOptions();
if ((options.targetJDK >= ClassFileConstants.JDK1_2
&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || fieldBinding != binding || indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic())
&& fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields
@@ -851,20 +885,20 @@
return this.resolvedType = getOtherFieldBindings(scope);
}
if (binding instanceof FieldBinding) {
- // check for forward references
FieldBinding fieldBinding = (FieldBinding) binding;
MethodScope methodScope = scope.methodScope();
- if (methodScope.enclosingSourceType() == fieldBinding.declaringClass
+ ReferenceBinding declaringClass = fieldBinding.declaringClass;
+ // check for forward references
+ if (this.indexOfFirstFieldBinding == 1
+ && methodScope.enclosingSourceType() == declaringClass
&& methodScope.lastVisibleFieldID >= 0
- && fieldBinding.id >= methodScope.lastVisibleFieldID) {
- if ((!fieldBinding.isStatic() || methodScope.isStatic)
- && this.indexOfFirstFieldBinding == 1) {
- scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType());
- }
+ && fieldBinding.id >= methodScope.lastVisibleFieldID
+ && (!fieldBinding.isStatic() || methodScope.isStatic)) {
+ scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType());
}
if (!fieldBinding.isStatic()
&& this.indexOfFirstFieldBinding == 1
- && scope.environment().options.getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
+ && scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding);
}
bits &= ~RestrictiveFlagMASK; // clear bits
@@ -886,7 +920,7 @@
TypeBinding type = (TypeBinding) binding;
if (isTypeUseDeprecated(type, scope))
scope.problemReporter().deprecatedType(type, this);
- return this.resolvedType = scope.convertToRawType(type);
+ return this.resolvedType = scope.environment().convertToRawType(type);
}
}
//========error cases===============
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
index 58c59a7..1c647f1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
@@ -72,15 +72,13 @@
public TypeBinding resolveType(BlockScope scope) {
constant = NotAConstant;
- TypeBinding type = this.resolvedType = this.qualification.resolveType(scope, true /* check bounds*/);
+ TypeBinding type = this.qualification.resolveType(scope, true /* check bounds*/);
if (type == null) return null;
- // X.this is not a raw type as denoting enclosing instance
- if (type.isRawType()) {
- RawTypeBinding rawType = (RawTypeBinding) type;
- type = this.resolvedType = rawType.type; // unwrap
- }
+ // X.this is not a param/raw type as denoting enclosing instance
+ this.resolvedType = type = type.erasure();
+
// the qualification MUST exactly match some enclosing type name
- // Its possible to qualify 'this' by the name of the current class
+ // It is possible to qualify 'this' by the name of the current class
int depth = 0;
this.currentCompatibleType = scope.referenceType().binding;
while (this.currentCompatibleType != null
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
index 004b9af..acffa43 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
@@ -43,7 +43,7 @@
ProblemReferenceBinding problemBinding = (ProblemReferenceBinding) this.resolvedType;
this.resolvedType = new ProblemReferenceBinding(
org.eclipse.jdt.core.compiler.CharOperation.subarray(this.tokens, 0, tokenIndex + 1),
- problemBinding.original,
+ problemBinding.closestMatch,
this.resolvedType.problemId());
}
}
@@ -75,13 +75,20 @@
if (((ClassScope) scope).detectHierarchyCycle(this.resolvedType, this, null)) // must connect hierarchy to find inherited member types
return null;
ReferenceBinding currentType = (ReferenceBinding) this.resolvedType;
- if (currentType.isGenericType()) {
- qualifiedType = scope.environment().createRawType(currentType, qualifiedType);
+ if (qualifiedType != null) {
+ boolean rawQualified;
+ if (currentType.isGenericType()) {
+ qualifiedType = scope.environment().createRawType(currentType, qualifiedType);
+ } else if ((rawQualified = qualifiedType.isRawType()) && !currentType.isStatic()) {
+ qualifiedType = scope.environment().createRawType((ReferenceBinding)currentType.erasure(), qualifiedType);
+ } else if (rawQualified || qualifiedType.isParameterizedType()) {
+ qualifiedType = scope.environment().createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType);
+ } else {
+ qualifiedType = currentType;
+ }
} else {
- qualifiedType = (qualifiedType != null && (qualifiedType.isRawType() || qualifiedType.isParameterizedType()))
- ? scope.createParameterizedType((ReferenceBinding)currentType.erasure(), null, qualifiedType)
- : currentType;
- }
+ qualifiedType = currentType.isGenericType() ? (ReferenceBinding)scope.environment().convertToRawType(currentType) : currentType;
+ }
}
this.resolvedType = qualifiedType;
return this.resolvedType;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java
index 40e5780..e3273fa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java
@@ -20,7 +20,7 @@
public class SingleMemberAnnotation extends Annotation {
public Expression memberValue;
- public MemberValuePair singlePair; // fake pair, only value has accurate positions
+ private MemberValuePair[] singlePairs; // fake pair set, only value has accurate positions
public SingleMemberAnnotation(TypeReference type, int sourceStart) {
this.type = type;
@@ -32,8 +32,13 @@
* @see org.eclipse.jdt.internal.compiler.ast.Annotation#memberValuePairs()
*/
public MemberValuePair[] memberValuePairs() {
- this.singlePair = new MemberValuePair(VALUE, this.memberValue.sourceStart, this.memberValue.sourceEnd, this.memberValue);
- return new MemberValuePair[] { singlePair };
+ if (this.singlePairs == null) {
+ this.singlePairs =
+ new MemberValuePair[]{
+ new MemberValuePair(VALUE, this.memberValue.sourceStart, this.memberValue.sourceEnd, this.memberValue)
+ };
+ }
+ return this.singlePairs;
}
public StringBuffer printExpression(int indent, StringBuffer output) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index 4bbe1a8..e79b6cc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -69,9 +69,22 @@
case Binding.FIELD : // assigning to a field
manageSyntheticAccessIfNecessary(currentScope, flowInfo, false /*write-access*/);
+ FieldBinding fieldBinding = (FieldBinding) binding;
+ ReferenceBinding declaringClass = fieldBinding.declaringClass;
+ // check if accessing enum static field in initializer
+ if (declaringClass.isEnum()) {
+ MethodScope methodScope = currentScope.methodScope();
+ SourceTypeBinding sourceType = currentScope.enclosingSourceType();
+ if (fieldBinding.isStatic()
+ && this.constant == NotAConstant
+ && !methodScope.isStatic
+ && (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+ && methodScope.isInsideInitializerOrConstructor()) {
+ currentScope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
+ }
+ }
// check if assigning a final field
- FieldBinding fieldBinding;
- if ((fieldBinding = (FieldBinding) binding).isFinal()) {
+ if (fieldBinding.isFinal()) {
// inside a context where allowed
if (!isCompound && fieldBinding.isBlankFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
if (flowInfo.isPotentiallyAssigned(fieldBinding)) {
@@ -121,10 +134,22 @@
if (valueRequired) {
manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
}
+ FieldBinding fieldBinding = (FieldBinding) binding;
+ ReferenceBinding declaringClass = fieldBinding.declaringClass;
+ // check if accessing enum static field in initializer
+ if (declaringClass.isEnum()) {
+ MethodScope methodScope = currentScope.methodScope();
+ SourceTypeBinding sourceType = currentScope.enclosingSourceType();
+ if (fieldBinding.isStatic()
+ && this.constant == NotAConstant
+ && !methodScope.isStatic
+ && (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
+ && methodScope.isInsideInitializerOrConstructor()) {
+ currentScope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
+ }
+ }
// check if reading a final blank field
- FieldBinding fieldBinding;
- if ((fieldBinding = (FieldBinding) binding).isBlankFinal()
- && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
+ if (fieldBinding.isBlankFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
}
@@ -153,27 +178,28 @@
bits &= ~RestrictiveFlagMASK; // clear bits
bits |= Binding.FIELD;
- if (!((FieldBinding) binding).isStatic()) {
+ MethodScope methodScope = scope.methodScope();
+ boolean isStatic = fieldBinding.isStatic();
+ if (!isStatic) {
// must check for the static status....
- if (scope.methodScope().isStatic) {
+ if (methodScope.isStatic) {
scope.problemReporter().staticFieldAccessToNonStaticVariable(this, fieldBinding);
- constant = NotAConstant;
+ this.constant = NotAConstant;
return fieldBinding.type;
}
}
- constant = FieldReference.getConstantFor(fieldBinding, this, true, scope);
+ this.constant = FieldReference.getConstantFor(fieldBinding, this, true, scope);
if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & IsStrictlyAssignedMASK) !=0))
scope.problemReporter().deprecatedField(fieldBinding, this);
- MethodScope ms = scope.methodScope();
if ((this.bits & IsStrictlyAssignedMASK) == 0
- && ms.enclosingSourceType() == fieldBinding.declaringClass
- && ms.lastVisibleFieldID >= 0
- && fieldBinding.id >= ms.lastVisibleFieldID) {
+ && methodScope.enclosingSourceType() == fieldBinding.declaringClass
+ && methodScope.lastVisibleFieldID >= 0
+ && fieldBinding.id >= methodScope.lastVisibleFieldID) {
//if the field is static and ms is not .... then it is valid
- if (!fieldBinding.isStatic() || ms.isStatic)
- scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType());
+ if (!fieldBinding.isStatic() || methodScope.isStatic)
+ scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType());
}
//====================================================
@@ -208,21 +234,27 @@
// optimizing assignment like: i = i + 1 or i = 1 + i
if (assignment.expression.isCompactableOperation()) {
BinaryExpression operation = (BinaryExpression) assignment.expression;
+ int operator = (operation.bits & OperatorMASK) >> OperatorSHIFT;
SingleNameReference variableReference;
if ((operation.left instanceof SingleNameReference) && ((variableReference = (SingleNameReference) operation.left).binding == binding)) {
// i = i + value, then use the variable on the right hand side, since it has the correct implicit conversion
- variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.right, (operation.bits & OperatorMASK) >> OperatorSHIFT, operation.implicitConversion, valueRequired);
+ variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.right, operator, operation.implicitConversion, valueRequired);
+ if (valueRequired) {
+ codeStream.generateImplicitConversion(assignment.implicitConversion);
+ }
return;
- }
- int operator = (operation.bits & OperatorMASK) >> OperatorSHIFT;
+ }
if ((operation.right instanceof SingleNameReference)
- && ((operator == PLUS) || (operator == MULTIPLY)) // only commutative operations
- && ((variableReference = (SingleNameReference) operation.right).binding == binding)
- && (operation.left.constant != NotAConstant) // exclude non constant expressions, since could have side-effect
- && (((operation.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString) // exclude string concatenation which would occur backwards
- && (((operation.right.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString)) { // exclude string concatenation which would occur backwards
+ && ((operator == PLUS) || (operator == MULTIPLY)) // only commutative operations
+ && ((variableReference = (SingleNameReference) operation.right).binding == binding)
+ && (operation.left.constant != NotAConstant) // exclude non constant expressions, since could have side-effect
+ && (((operation.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString) // exclude string concatenation which would occur backwards
+ && (((operation.right.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString)) { // exclude string concatenation which would occur backwards
// i = value + i, then use the variable on the right hand side, since it has the correct implicit conversion
variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.left, operator, operation.implicitConversion, valueRequired);
+ if (valueRequired) {
+ codeStream.generateImplicitConversion(assignment.implicitConversion);
+ }
return;
}
}
@@ -308,7 +340,7 @@
codeStream.generateConstant(fieldBinding.constant(), implicitConversion);
}
} else {
- if (valueRequired || currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
+ if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
boolean isStatic = fieldBinding.isStatic();
if (!isStatic) {
if ((bits & DepthMASK) != 0) {
@@ -462,10 +494,12 @@
break;
default :
// promote the array reference to the suitable operation type
- codeStream.generateImplicitConversion(implicitConversion);
+ if (this.genericCast != null)
+ codeStream.checkcast(this.genericCast);
+ codeStream.generateImplicitConversion(this.implicitConversion);
// generate the increment value (will by itself be promoted to the operation value)
if (expression == IntLiteral.One){ // prefix operation
- codeStream.generateConstant(expression.constant, implicitConversion);
+ codeStream.generateConstant(expression.constant, this.implicitConversion);
} else {
expression.generateCode(currentScope, codeStream, true);
}
@@ -533,11 +567,13 @@
}
}
}
- codeStream.generateImplicitConversion(implicitConversion);
- codeStream.generateConstant(postIncrement.expression.constant, implicitConversion);
+ if (this.genericCast != null)
+ codeStream.checkcast(this.genericCast);
+ codeStream.generateImplicitConversion(this.implicitConversion);
+ codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
codeStream.sendOperator(postIncrement.operator, this.implicitConversion & COMPILE_TYPE_MASK);
- codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
- fieldStore(codeStream, fieldBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], false);
+ codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
+ fieldStore(codeStream, fieldBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[WRITE], false);
// no need for generic cast
return;
case Binding.LOCAL : // assigning to a local variable
@@ -564,7 +600,7 @@
codeStream.generateImplicitConversion(implicitConversion);
codeStream.generateConstant(postIncrement.expression.constant, implicitConversion);
codeStream.sendOperator(postIncrement.operator, this.implicitConversion & COMPILE_TYPE_MASK);
- codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+ codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
codeStream.store(localBinding, false);
}
@@ -624,7 +660,7 @@
&& !this.actualReceiverType.isArrayType()
&& fieldBinding.declaringClass != null // array.length
&& !fieldBinding.isConstantValue()) {
- CompilerOptions options = currentScope.environment().options;
+ CompilerOptions options = currentScope.compilerOptions();
if ((options.targetJDK >= ClassFileConstants.JDK1_2
&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic())
&& fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields
@@ -682,7 +718,7 @@
if ((this.bits & IsStrictlyAssignedMASK) == 0) {
constant = variable.constant();
if (fieldType != null)
- fieldType = fieldType.capture(); // perform capture conversion if read access
+ fieldType = fieldType.capture(scope, this.sourceEnd); // perform capture conversion if read access
} else {
constant = NotAConstant;
}
@@ -690,14 +726,14 @@
}
// a field
FieldBinding field = (FieldBinding) this.binding;
- if (!field.isStatic() && scope.environment().options.getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
+ if (!field.isStatic() && scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
scope.problemReporter().unqualifiedFieldAccess(this, field);
}
// perform capture conversion if read access
TypeBinding fieldType = checkFieldAccess(scope);
return this.resolvedType =
(((this.bits & IsStrictlyAssignedMASK) == 0)
- ? fieldType.capture()
+ ? fieldType.capture(scope, this.sourceEnd)
: fieldType);
}
@@ -710,7 +746,7 @@
TypeBinding type = (TypeBinding)binding;
if (isTypeUseDeprecated(type, scope))
scope.problemReporter().deprecatedType(type, this);
- return this.resolvedType = scope.convertToRawType(type);
+ return this.resolvedType = scope.environment().convertToRawType(type);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
index a560b5e..9002931 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
@@ -63,7 +63,7 @@
}
if (isTypeUseDeprecated(memberType, scope))
scope.problemReporter().deprecatedType(memberType, this);
- return this.resolvedType = scope.convertToRawType(memberType);
+ return this.resolvedType = scope.environment().convertToRawType(memberType);
}
public void traverse(ASTVisitor visitor, BlockScope scope) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index fe0e0fb..ccaa21c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -57,6 +57,7 @@
}
ArrayBinding varArgsType = (ArrayBinding) params[varArgIndex]; // parameterType has to be an array type
+ ArrayBinding codeGenVarArgsType = (ArrayBinding) binding.parameters[varArgIndex].erasure();
int elementsTypeID = varArgsType.elementsType().id;
int argLength = arguments == null ? 0 : arguments.length;
@@ -65,7 +66,7 @@
// called with (argLength - lastIndex) elements : foo(1, 2) or foo(1, 2, 3, 4)
// need to gen elements into an array, then gen each remaining element into created array
codeStream.generateInlinedValue(argLength - varArgIndex);
- codeStream.newArray(varArgsType); // create a mono-dimensional array
+ codeStream.newArray(codeGenVarArgsType); // create a mono-dimensional array
for (int i = varArgIndex; i < argLength; i++) {
codeStream.dup();
codeStream.generateInlinedValue(i - varArgIndex);
@@ -84,7 +85,7 @@
// right number but not directly compatible or too many arguments - wrap extra into array
// need to gen elements into an array, then gen each remaining element into created array
codeStream.generateInlinedValue(1);
- codeStream.newArray(varArgsType); // create a mono-dimensional array
+ codeStream.newArray(codeGenVarArgsType); // create a mono-dimensional array
codeStream.dup();
codeStream.generateInlinedValue(0);
arguments[varArgIndex].generateCode(currentScope, codeStream, true);
@@ -94,7 +95,7 @@
// scenario: foo(1) --> foo(1, new int[0])
// generate code for an empty array of parameterType
codeStream.generateInlinedValue(0);
- codeStream.newArray(varArgsType); // create a mono-dimensional array
+ codeStream.newArray(codeGenVarArgsType); // create a mono-dimensional array
}
} else if (arguments != null) { // standard generation for method arguments
for (int i = 0, max = arguments.length; i < max; i++)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
index 26e4cf1..5df3b6a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
@@ -32,6 +32,8 @@
public int caseCount;
int[] constants;
+ public SyntheticMethodBinding synthetic; // use for switch on enums types
+
// for local variables table attributes
int preSwitchInitStateIndex = -1;
int mergedInitStateIndex = -1;
@@ -75,6 +77,11 @@
}
}
+ final TypeBinding resolvedTypeBinding = this.expression.resolvedType;
+ if (caseCount > 0 && resolvedTypeBinding.isEnum()) {
+ final SourceTypeBinding sourceTypeBinding = this.scope.classScope().referenceContext.binding;
+ this.synthetic = sourceTypeBinding.addSyntheticMethodForSwitchEnum(resolvedTypeBinding);
+ }
// if no default case, then record it may jump over the block directly to the end
if (defaultCase == null) {
// only retain the potential initializations
@@ -120,8 +127,24 @@
if (defaultCase != null) {
defaultCase.targetLabel = defaultLabel;
}
- // generate expression testes
- expression.generateCode(currentScope, codeStream, needSwitch);
+
+ final TypeBinding resolvedType = this.expression.resolvedType;
+ if (resolvedType.isEnum()) {
+ if (needSwitch) {
+ // go through the translation table
+ codeStream.invokestatic(this.synthetic);
+ expression.generateCode(currentScope, codeStream, true);
+ // get enum constant ordinal()
+ codeStream.invokeEnumOrdinal(resolvedType.constantPoolName());
+ codeStream.iaload();
+ } else {
+ // no need to go through the translation table
+ expression.generateCode(currentScope, codeStream, false);
+ }
+ } else {
+ // generate expression
+ expression.generateCode(currentScope, codeStream, needSwitch); // value required (switch without cases)
+ }
// generate the appropriate switch table/lookup bytecode
if (needSwitch) {
int[] sortedIndexes = new int[this.caseCount];
@@ -133,17 +156,13 @@
System.arraycopy(this.constants, 0, (localKeysCopy = new int[this.caseCount]), 0, this.caseCount);
CodeStream.sort(localKeysCopy, 0, this.caseCount - 1, sortedIndexes);
- // for enum constants, actually switch on constant ordinal()
- if (this.expression.resolvedType.isEnum()) {
- codeStream.invokeEnumOrdinal(this.expression.resolvedType.constantPoolName());
- }
int max = localKeysCopy[this.caseCount - 1];
int min = localKeysCopy[0];
if ((long) (caseCount * 2.5) > ((long) max - (long) min)) {
// work-around 1.3 VM bug, if max>0x7FFF0000, must use lookup bytecode
// see http://dev.eclipse.org/bugs/show_bug.cgi?id=21557
- if (max > 0x7FFF0000 && currentScope.environment().options.complianceLevel < ClassFileConstants.JDK1_4) {
+ if (max > 0x7FFF0000 && currentScope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_4) {
codeStream.lookupswitch(defaultLabel, this.constants, sortedIndexes, caseLabels);
} else {
@@ -297,7 +316,7 @@
}
// for enum switch, check if all constants are accounted for (if no default)
if (isEnumSwitch && defaultCase == null
- && upperScope.environment().options.getSeverity(CompilerOptions.IncompleteEnumSwitch) != ProblemSeverities.Ignore) {
+ && upperScope.compilerOptions().getSeverity(CompilerOptions.IncompleteEnumSwitch) != ProblemSeverities.Ignore) {
int constantCount = this.constants == null ? 0 : this.constants.length; // could be null if no case statement
if (constantCount == caseCount // ignore diagnosis if unresolved constants
&& caseCount != ((ReferenceBinding)expressionType).enumConstantCount()) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
index c5820ab..cbcb0ef 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
@@ -64,7 +64,7 @@
exceptionType = exception.resolveTypeExpecting(scope, scope.getJavaLangThrowable());
if (exceptionType == NullBinding
- && scope.environment().options.complianceLevel <= ClassFileConstants.JDK1_3){
+ && scope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3){
// if compliant with 1.4, this problem will not be reported
scope.problemReporter().cannotThrowNull(this);
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index 9431f4a..2518cf8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -208,7 +208,7 @@
} else {
if (this.isSubRoutineEscaping) {
finallyMode = FINALLY_DOES_NOT_COMPLETE;
- } else if (scope.environment().options.inlineJsrBytecode) {
+ } else if (scope.compilerOptions().inlineJsrBytecode) {
finallyMode = FINALLY_MUST_BE_INLINED;
} else {
finallyMode = FINALLY_SUBROUTINE;
@@ -411,9 +411,11 @@
if (this.isSubRoutineEscaping) {
codeStream.goto_(this.subRoutineStartLabel);
} else {
- if (currentScope.environment().options.inlineJsrBytecode) {
+ if (currentScope.compilerOptions().inlineJsrBytecode) {
// cannot use jsr bytecode, then simply inline the subroutine
+ this.exitAnyExceptionHandler();
this.finallyBlock.generateCode(currentScope, codeStream);
+ this.enterAnyExceptionHandler(codeStream);
} else {
// classic subroutine invocation, distinguish case of non-returning subroutine
codeStream.jsr(this.subRoutineStartLabel);
@@ -463,7 +465,7 @@
MethodScope methodScope = scope.methodScope();
// the type does not matter as long as it is not a base type
- if (!upperScope.environment().options.inlineJsrBytecode) {
+ if (!upperScope.compilerOptions().inlineJsrBytecode) {
this.returnAddressVariable =
new LocalVariableBinding(SecretReturnName, upperScope.getJavaLangObject(), AccDefault, false);
finallyScope.addLocalVariable(returnAddressVariable);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 9722d1d..177ba8b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -11,7 +11,6 @@
package org.eclipse.jdt.internal.compiler.ast;
import org.eclipse.jdt.core.compiler.*;
-import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
@@ -51,7 +50,7 @@
public CompilationResult compilationResult;
public MethodDeclaration[] missingAbstractMethods;
public Javadoc javadoc;
-
+
public QualifiedAllocationExpression allocation; // for anonymous only
public TypeDeclaration enclosingType; // for member types only
@@ -307,7 +306,7 @@
return this.compilationResult;
}
-
+
public ConstructorDeclaration createDefaultConstructor(
boolean needExplicitConstructorCall,
boolean needToInsert) {
@@ -626,8 +625,8 @@
*/
public void internalAnalyseCode(FlowContext flowContext, FlowInfo flowInfo) {
- if (this.binding.isPrivate() && !this.binding.isPrivateUsed()) {
- if (!scope.referenceCompilationUnit().compilationResult.hasSyntaxError()) {
+ if ((this.binding.isPrivate()/* || (this.binding.tagBits & (TagBits.IsAnonymousType|TagBits.IsLocalType)) == TagBits.IsLocalType*/) && !this.binding.isUsed()) {
+ if (!scope.referenceCompilationUnit().compilationResult.hasSyntaxError) {
scope.problemReporter().unusedPrivateType(this);
}
}
@@ -764,7 +763,7 @@
// M() { this(new Object() { void baz() { foo(); }}); } // access to #foo() indirects through constructor synthetic arg: val$this$0
// }
//}
- if (!methodScope.isStatic && methodScope.isConstructorCall && currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_5) {
+ if (!methodScope.isStatic && methodScope.isConstructorCall && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5) {
ReferenceBinding enclosing = nestedType.enclosingType();
if (enclosing.isNestedType()) {
NestedTypeBinding nestedEnclosing = (NestedTypeBinding)enclosing;
@@ -974,7 +973,7 @@
this.scope.problemReporter().undocumentedEmptyBlock(this.bodyStart-1, this.bodyEnd);
}
boolean needSerialVersion =
- this.scope.environment().options.getSeverity(CompilerOptions.MissingSerialVersion) != ProblemSeverities.Ignore
+ this.scope.compilerOptions().getSeverity(CompilerOptions.MissingSerialVersion) != ProblemSeverities.Ignore
&& sourceType.isClass()
&& !sourceType.isAbstract()
&& sourceType.findSuperTypeErasingTo(T_JavaIoSerializable, false /*Serializable is not a class*/) != null;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
index 4b5511f..bec3a42 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
@@ -42,16 +42,26 @@
}
}
- public void resolve(ClassScope scope) {
+ private void internalResolve(Scope scope, boolean staticContext) {
// detect variable/type name collisions
if (this.binding != null) {
- Scope outerScope = scope.parent;
- Binding existingType = outerScope.getBinding(this.name, Binding.TYPE, this, false);
- if (existingType != null && this.binding != existingType && existingType.isValidBinding()) {
+ Binding existingType = scope.parent.getBinding(this.name, Binding.TYPE, this, false);
+ if (existingType != null
+ && this.binding != existingType
+ && existingType.isValidBinding()
+ && (existingType.kind() != Binding.TYPE_PARAMETER || !staticContext)) {
scope.problemReporter().typeHiding(this, existingType);
}
}
}
+
+ public void resolve(BlockScope scope) {
+ internalResolve(scope, scope.methodScope().isStatic);
+ }
+
+ public void resolve(ClassScope scope) {
+ internalResolve(scope, scope.enclosingSourceType().isStatic());
+ }
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.compiler.ast.AstNode#print(int, java.lang.StringBuffer)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
index 2f9f08e..8eff119 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
@@ -130,7 +130,7 @@
}
if (isTypeUseDeprecated(this.resolvedType, blockScope))
reportDeprecatedType(blockScope);
- return this.resolvedType = blockScope.convertToRawType(this.resolvedType);
+ return this.resolvedType = blockScope.environment().convertToRawType(this.resolvedType);
}
public TypeBinding resolveType(ClassScope classScope) {
// handle the error here
@@ -147,7 +147,7 @@
}
if (isTypeUseDeprecated(this.resolvedType, classScope))
reportDeprecatedType(classScope);
- return this.resolvedType = classScope.convertToRawType(this.resolvedType);
+ return this.resolvedType = classScope.environment().convertToRawType(this.resolvedType);
}
public TypeBinding resolveTypeArgument(BlockScope blockScope, ReferenceBinding genericType, int rank) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
index dc81aa9..76a9062 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
@@ -214,11 +214,10 @@
}
int expressionTypeID = expressionType.id;
// autoboxing support
- LookupEnvironment env = scope.environment();
- boolean use15specifics = env.options.sourceLevel >= JDK1_5;
+ boolean use15specifics = scope.compilerOptions().sourceLevel >= JDK1_5;
if (use15specifics) {
if (!expressionType.isBaseType()) {
- expressionTypeID = env.computeBoxingType(expressionType).id;
+ expressionTypeID = scope.environment().computeBoxingType(expressionType).id;
}
}
if (expressionTypeID > 15) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
index 4bc538e..99321ef 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
@@ -66,7 +66,7 @@
FlowInfo actionInfo;
FlowInfo exitBranch;
if (action == null
- || (action.isEmptyBlock() && currentScope.environment().options.complianceLevel <= ClassFileConstants.JDK1_3)) {
+ || (action.isEmptyBlock() && currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3)) {
condLoopContext.complainOnDeferredChecks(currentScope, condInfo);
if (isConditionTrue) {
return FlowInfo.DEAD_END;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
index 3d13e57..643e073 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
@@ -801,6 +801,9 @@
if ((this.getTagBits() & TagBits.AnnotationTargetMASK|TagBits.AnnotationDeprecated|TagBits.AnnotationRetentionMASK) != (newClassFile.getTagBits() & TagBits.AnnotationTargetMASK|TagBits.AnnotationDeprecated|TagBits.AnnotationRetentionMASK))
return true;
+ // generic signature
+ if (!CharOperation.equals(this.getGenericSignature(), newClassFile.getGenericSignature()))
+ return true;
// superclass
if (!CharOperation.equals(this.getSuperclassName(), newClassFile.getSuperclassName()))
return true;
@@ -895,6 +898,9 @@
}
}
private boolean hasStructuralFieldChanges(FieldInfo currentFieldInfo, FieldInfo otherFieldInfo) {
+ // generic signature
+ if (!CharOperation.equals(currentFieldInfo.getGenericSignature(), otherFieldInfo.getGenericSignature()))
+ return true;
if (currentFieldInfo.getModifiers() != otherFieldInfo.getModifiers())
return true;
if ((currentFieldInfo.getTagBits() & TagBits.AnnotationDeprecated) != (otherFieldInfo.getTagBits() & TagBits.AnnotationDeprecated))
@@ -936,6 +942,9 @@
return false;
}
private boolean hasStructuralMethodChanges(MethodInfo currentMethodInfo, MethodInfo otherMethodInfo) {
+ // generic signature
+ if (!CharOperation.equals(currentMethodInfo.getGenericSignature(), otherMethodInfo.getGenericSignature()))
+ return true;
if (currentMethodInfo.getModifiers() != otherMethodInfo.getModifiers())
return true;
if ((currentMethodInfo.getTagBits() & TagBits.AnnotationDeprecated) != (otherMethodInfo.getTagBits() & TagBits.AnnotationDeprecated))
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
index 23c238f..86def37 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
@@ -118,7 +118,7 @@
readOffset += 2;
break;
case '@' :
- readOffset += decodeAnnotation(readOffset);
+ readOffset = decodeAnnotation(readOffset);
break;
case '[' :
int numberOfValues = u2At(readOffset);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
index 54c4829..2e485ad 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
@@ -110,7 +110,7 @@
readOffset += 2;
break;
case '@' :
- readOffset += decodeAnnotation(readOffset);
+ readOffset = decodeAnnotation(readOffset);
break;
case '[' :
int numberOfValues = u2At(readOffset);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index ca2388c..334bc9a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -10,11 +10,13 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.codegen;
+import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.classfmt.*;
+import org.eclipse.jdt.internal.compiler.env.IConstants;
import org.eclipse.jdt.internal.compiler.flow.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
@@ -32,7 +34,7 @@
public byte[] bCodeStream;
public int pcToSourceMapSize;
public int[] pcToSourceMap = new int[24];
- public int lastEntryPC; // last entry recorded
+ public int lastEntryPC; // last entry recorded
public int[] lineSeparatorPositions;
public int position; // So when first set can be incremented
public int classFileOffset;
@@ -1796,7 +1798,7 @@
ASTNode invocationSite) {
// supplying enclosing instance for the anonymous type's superclass
- ReferenceBinding checkedTargetType = targetType.isAnonymousType() ? targetType.superclass() : targetType;
+ ReferenceBinding checkedTargetType = targetType.isAnonymousType() ? (ReferenceBinding)targetType.superclass().erasure() : targetType;
boolean hasExtraEnclosingInstance = enclosingInstance != null;
if (hasExtraEnclosingInstance
&& (!checkedTargetType.isNestedType() || checkedTargetType.isStatic())) {
@@ -1809,7 +1811,7 @@
if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {
ReferenceBinding targetEnclosingType = checkedTargetType.enclosingType();
- long compliance = currentScope.environment().options.complianceLevel;
+ long compliance = currentScope.compilerOptions().complianceLevel;
// deny access to enclosing instance argument for allocation and super constructor call (if 1.4)
// always consider it if complying to 1.5
@@ -1998,32 +2000,89 @@
this.invokeJavaLangIllegalArgumentExceptionStringConstructor();
this.athrow();
}
+public void generateSyntheticBodyForSwitchTable(SyntheticMethodBinding methodBinding) {
+ ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope;
+ initializeMaxLocals(methodBinding);
+ final Label nullLabel = new Label(this);
+ FieldBinding syntheticFieldBinding = methodBinding.targetReadField;
+
+ this.getstatic(syntheticFieldBinding);
+ this.dup();
+ this.ifnull(nullLabel);
+ final int stackSizeForIf = this.stackDepth;
+ this.areturn();
+ nullLabel.place();
+ this.stackDepth = stackSizeForIf;
+ this.pop();
+ ReferenceBinding enumBinding = (ReferenceBinding) methodBinding.targetEnumType;
+ char[] signature = "()".toCharArray(); //$NON-NLS-1$
+ ArrayBinding arrayBinding = scope.createArrayType(enumBinding, 1);
+ signature = CharOperation.concat(signature, arrayBinding.constantPoolName());
+ this.invoke(OPC_invokestatic, 0, 1, enumBinding.constantPoolName(), TypeConstants.VALUES, signature);
+ this.arraylength();
+ this.newarray(INT_ARRAY);
+ this.astore_0();
+ final FieldBinding[] fields = enumBinding.fields();
+ if (fields != null) {
+ for (int i = 0, max = fields.length; i < max; i++) {
+ FieldBinding fieldBinding = fields[i];
+ if ((fieldBinding.getAccessFlags() & IConstants.AccEnum) != 0) {
+ final Label endLabel = new Label(this);
+ final ExceptionLabel anyExceptionHandler = new ExceptionLabel(this, BaseTypes.LongBinding /* represents NoSuchFieldError*/);
+ this.aload_0();
+ this.getstatic(fieldBinding);
+ this.invokeEnumOrdinal(enumBinding.constantPoolName());
+ this.generateInlinedValue(fieldBinding.id);
+ this.iastore();
+ anyExceptionHandler.placeEnd();
+ this.goto_(endLabel);
+ // Generate the body of the exception handler
+ final int saveStackSize = stackDepth;
+ stackDepth = 1;
+ anyExceptionHandler.place();
+ this.pop(); // we don't use it so we can pop it
+ stackDepth = saveStackSize;
+ endLabel.place();
+ }
+ }
+ }
+ this.aload_0();
+ this.dup();
+ this.putstatic(syntheticFieldBinding);
+ areturn();
+}
public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) {
initializeMaxLocals(accessBinding);
FieldBinding fieldBinding = accessBinding.targetReadField;
- TypeBinding type;
if (fieldBinding.isStatic())
this.getstatic(fieldBinding);
else {
this.aload_0();
this.getfield(fieldBinding);
}
- if ((type = fieldBinding.type).isBaseType()) {
- if (type == IntBinding)
+ switch (fieldBinding.type.id) {
+// case T_void :
+// this.return_();
+// break;
+ case T_boolean :
+ case T_byte :
+ case T_char :
+ case T_short :
+ case T_int :
this.ireturn();
- else
- if (type == FloatBinding)
- this.freturn();
- else
- if (type == LongBinding)
- this.lreturn();
- else
- if (type == DoubleBinding)
- this.dreturn();
- else
- this.ireturn();
- } else
- this.areturn();
+ break;
+ case T_long :
+ this.lreturn();
+ break;
+ case T_float :
+ this.freturn();
+ break;
+ case T_double :
+ this.dreturn();
+ break;
+ default :
+ this.areturn();
+ }
}
public void generateSyntheticBodyForFieldWriteAccess(SyntheticMethodBinding accessBinding) {
initializeMaxLocals(accessBinding);
@@ -2038,17 +2097,17 @@
}
this.return_();
}
-public void generateSyntheticBodyForMethodAccess(SyntheticMethodBinding accessBinding) {
+public void generateSyntheticBodyForMethodAccess(SyntheticMethodBinding accessMethod) {
- initializeMaxLocals(accessBinding);
- MethodBinding methodBinding = accessBinding.targetMethod;
- TypeBinding[] parameters = methodBinding.parameters;
+ initializeMaxLocals(accessMethod);
+ MethodBinding targetMethod = accessMethod.targetMethod;
+ TypeBinding[] parameters = targetMethod.parameters;
int length = parameters.length;
- TypeBinding[] arguments = accessBinding.kind == SyntheticMethodBinding.BridgeMethod
- ? accessBinding.parameters
+ TypeBinding[] arguments = accessMethod.kind == SyntheticMethodBinding.BridgeMethod
+ ? accessMethod.parameters
: null;
int resolvedPosition;
- if (methodBinding.isStatic())
+ if (targetMethod.isStatic())
resolvedPosition = 0;
else {
this.aload_0();
@@ -2069,42 +2128,48 @@
else
resolvedPosition++;
}
- TypeBinding type;
- if (methodBinding.isStatic())
- this.invokestatic(methodBinding);
+ if (targetMethod.isStatic())
+ this.invokestatic(targetMethod);
else {
- if (methodBinding.isConstructor()
- || methodBinding.isPrivate()
+ if (targetMethod.isConstructor()
+ || targetMethod.isPrivate()
// qualified super "X.super.foo()" targets methods from superclass
- || accessBinding.kind == SyntheticMethodBinding.SuperMethodAccess){
- this.invokespecial(methodBinding);
+ || accessMethod.kind == SyntheticMethodBinding.SuperMethodAccess){
+ this.invokespecial(targetMethod);
} else {
- if (methodBinding.declaringClass.isInterface()) { // interface or annotation type
- this.invokeinterface(methodBinding);
+ if (targetMethod.declaringClass.isInterface()) { // interface or annotation type
+ this.invokeinterface(targetMethod);
} else {
- this.invokevirtual(methodBinding);
+ this.invokevirtual(targetMethod);
}
}
}
- if ((type = methodBinding.returnType).isBaseType())
- if (type == VoidBinding)
+ switch (targetMethod.returnType.id) {
+ case T_void :
this.return_();
- else
- if (type == IntBinding)
- this.ireturn();
- else
- if (type == FloatBinding)
- this.freturn();
- else
- if (type == LongBinding)
- this.lreturn();
- else
- if (type == DoubleBinding)
- this.dreturn();
- else
- this.ireturn();
- else
- this.areturn();
+ break;
+ case T_boolean :
+ case T_byte :
+ case T_char :
+ case T_short :
+ case T_int :
+ this.ireturn();
+ break;
+ case T_long :
+ this.lreturn();
+ break;
+ case T_float :
+ this.freturn();
+ break;
+ case T_double :
+ this.dreturn();
+ break;
+ default :
+ TypeBinding accessErasure = accessMethod.returnType.erasure();
+ if (!targetMethod.returnType.isCompatibleWith(accessErasure))
+ this.checkcast(accessErasure); // for bridge methods
+ this.areturn();
+ }
}
public void generateBoxingConversion(int unboxedTypeID) {
switch (unboxedTypeID) {
@@ -5421,7 +5486,7 @@
public void reset(AbstractMethodDeclaration referenceMethod, ClassFile targetClassFile) {
init(targetClassFile);
this.methodDeclaration = referenceMethod;
- preserveUnusedLocals = referenceMethod.scope.problemReporter().options.preserveAllLocalVariables;
+ this.preserveUnusedLocals = referenceMethod.scope.compilerOptions().preserveAllLocalVariables;
initializeMaxLocals(referenceMethod.binding);
}
/**
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
index 15fd1bc..745edf0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
@@ -150,6 +150,7 @@
public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); //$NON-NLS-1$
public static final char[] JavaLangLongConstantPoolName = "java/lang/Long".toCharArray(); //$NON-NLS-1$
public static final char[] JavaLangNoClassDefFoundErrorConstantPoolName = "java/lang/NoClassDefFoundError".toCharArray(); //$NON-NLS-1$
+ public static final char[] JavaLangNoSuchFieldErrorConstantPoolName = "java/lang/NoSuchFieldError".toCharArray(); //$NON-NLS-1$
public static final char[] JavaLangObjectConstantPoolName = "java/lang/Object".toCharArray(); //$NON-NLS-1$
public static final char[] JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME = "java/lang/reflect/AccessibleObject".toCharArray(); //$NON-NLS-1$
public static final char[] JAVALANGREFLECTARRAY_CONSTANTPOOLNAME = "java/lang/reflect/Array".toCharArray(); //$NON-NLS-1$
@@ -177,6 +178,7 @@
public static final char[] Next = "next".toCharArray();//$NON-NLS-1$
public static final char[] NextSignature = "()Ljava/lang/Object;".toCharArray();//$NON-NLS-1$
public static final char[] ObjectConstrSignature = "(Ljava/lang/Object;)V".toCharArray(); //$NON-NLS-1$
+ public static final char[] ObjectSignature = "Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
public static final char[] Ordinal = "ordinal".toCharArray(); //$NON-NLS-1$
public static final char[] OrdinalSignature = "()I".toCharArray(); //$NON-NLS-1$
public static final char[] Out = "out".toCharArray(); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java
index 4a51ece..408acf0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java
@@ -25,6 +25,10 @@
public AccessRuleSet(AccessRule[] accessRules) {
this.accessRules = accessRules;
}
+ public AccessRuleSet(AccessRule[] accessRules, String messageTemplate) {
+ this.accessRules = accessRules;
+ this.messageTemplate = messageTemplate;
+ }
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@@ -50,7 +54,7 @@
/**
* Select the first access rule which is violated when accessing a given type, or null if no 'non accessible' access rule applies.
- * Target type file path is formed as: "org/eclipse/jdt/core/JavaCore.java".
+ * Target type file path is formed as: "org/eclipse/jdt/core/JavaCore".
*/
public AccessRestriction getViolatedRestriction(char[] targetTypeFilePath) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
index ae7ba28..629e08d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
@@ -59,10 +59,8 @@
this.initsOnExceptions = new UnconditionalFlowInfo[count];
for (int i = 0; i < count; i++) {
this.indexes.put(handledExceptions[i], i); // key type -> value index
- boolean isUnchecked =
- (scope.compareUncheckedException(handledExceptions[i]) != NotRelated);
int cacheIndex = i / BitCacheSize, bitMask = 1 << (i % BitCacheSize);
- if (isUnchecked) {
+ if (handledExceptions[i].isUncheckedException(true)) {
isReached[cacheIndex] |= bitMask;
this.initsOnExceptions[i] = flowInfo.copy().unconditionalInits();
} else {
@@ -77,7 +75,7 @@
MethodScope scope = method.scope;
// can optionally skip overriding methods
if ((method.binding.modifiers & (CompilerModifiers.AccOverriding | CompilerModifiers.AccImplementing)) != 0
- && !scope.environment().options.reportUnusedDeclaredThrownExceptionWhenOverriding) {
+ && !scope.compilerOptions().reportUnusedDeclaredThrownExceptionWhenOverriding) {
return;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
index ce08eae..8964f18 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
@@ -139,8 +139,7 @@
for (int i = 0; i < raisedCount; i++) {
TypeBinding raisedException;
if ((raisedException = raisedExceptions[i]) != null) {
- if (raisedException.isCompatibleWith(scope.getJavaLangRuntimeException())
- || raisedException.isCompatibleWith(scope.getJavaLangError())) {
+ if (raisedException.isUncheckedException(false)) {
remainingCount--;
raisedExceptions[i] = null;
}
@@ -248,8 +247,7 @@
}
// method treatment for unchecked exceptions
if (exceptionContext.isMethodContext) {
- if (raisedException.isCompatibleWith(scope.getJavaLangRuntimeException())
- || raisedException.isCompatibleWith(scope.getJavaLangError()))
+ if (raisedException.isUncheckedException(false))
return;
// anonymous constructors are allowed to throw any exceptions (their thrown exceptions
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index 703c0f0..3c5c088 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -99,6 +99,8 @@
public static final String OPTION_ReportIncompleteEnumSwitch = "org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch"; //$NON-NLS-1$
public static final String OPTION_ReportForbiddenReference = "org.eclipse.jdt.core.compiler.problem.forbiddenReference"; //$NON-NLS-1$
public static final String OPTION_ReportDiscouragedReference = "org.eclipse.jdt.core.compiler.problem.discouragedReference"; //$NON-NLS-1$
+ public static final String OPTION_SuppressWarnings = "org.eclipse.jdt.core.compiler.problem.suppressWarnings"; //$NON-NLS-1$
+ public static final String OPTION_ReportUnhandledWarningToken = "org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"; //$NON-NLS-1$
// Backward compatibility
public static final String OPTION_ReportInvalidAnnotation = "org.eclipse.jdt.core.compiler.problem.invalidAnnotation"; //$NON-NLS-1$
@@ -177,6 +179,14 @@
public static final long IncompleteEnumSwitch = ASTNode.Bit42L;
public static final long MissingDeprecatedAnnotation = ASTNode.Bit43L;
public static final long DiscouragedReference = ASTNode.Bit44L;
+ public static final long UnhandledWarningToken = ASTNode.Bit45L;
+
+ // TODO (olivier) remove once http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21540 is fixed
+ private static final int IntMissingSerialVersion = (int) (MissingSerialVersion >>> 32);
+ private static final int IntAutoBoxing = (int) (Autoboxing >>> 32);
+ private static final int IntTypeParameterHiding = (int) (TypeParameterHiding >>> 32);
+ private static final int IntIncompleteEnumSwitch = (int) (IncompleteEnumSwitch >>> 32);
+ private static final int IntMissingDeprecatedAnnotation = (int) (MissingDeprecatedAnnotation >>> 32);
// Default severity level for handlers
public long errorThreshold = 0;
@@ -202,6 +212,9 @@
| AnnotationSuperInterface
| TypeParameterHiding
| FinalParameterBound
+ | UnhandledWarningToken
+ | UnusedLocalVariable
+ | UnusedPrivateMember
/*| NullReference*/;
// Debug attributes
@@ -264,18 +277,20 @@
// check missing javadoc tags
public int reportMissingJavadocTagsVisibility = AccPrivate;
- public boolean reportMissingJavadocTagsOverriding = true;
+ public boolean reportMissingJavadocTagsOverriding = false;
// check missing javadoc comments
public int reportMissingJavadocCommentsVisibility = AccPublic;
- public boolean reportMissingJavadocCommentsOverriding = true;
-
+ public boolean reportMissingJavadocCommentsOverriding = false;
+
// JSR bytecode inlining
public boolean inlineJsrBytecode = false;
// javadoc comment support
public boolean docCommentSupport = false;
+ // suppress warning annotation
+ public boolean suppressWarnings = true;
/**
* Initializing the compiler options with defaults
@@ -369,15 +384,17 @@
optionsMap.put(OPTION_ReportSpecialParameterHidingField, this.reportSpecialParameterHidingField ? ENABLED : DISABLED);
optionsMap.put(OPTION_MaxProblemPerUnit, String.valueOf(this.maxProblemsPerUnit));
optionsMap.put(OPTION_InlineJsr, this.inlineJsrBytecode ? ENABLED : DISABLED);
- optionsMap.put(OPTION_ReportNullReference, getSeverityString(NullReference));
+ optionsMap.put(OPTION_ReportNullReference, getSeverityString(NullReference));
+ optionsMap.put(OPTION_SuppressWarnings, this.suppressWarnings ? ENABLED : DISABLED);
+ optionsMap.put(OPTION_ReportUnhandledWarningToken, getSeverityString(UnhandledWarningToken));
return optionsMap;
}
public int getSeverity(long irritant) {
- if((this.warningThreshold & irritant) != 0)
- return Warning;
if((this.errorThreshold & irritant) != 0)
return Error;
+ if((this.warningThreshold & irritant) != 0)
+ return Warning;
return Ignore;
}
@@ -553,6 +570,13 @@
}
}
}
+ if ((optionValue = optionsMap.get(OPTION_SuppressWarnings)) != null) {
+ if (ENABLED.equals(optionValue)) {
+ this.suppressWarnings = true;
+ } else if (DISABLED.equals(optionValue)) {
+ this.suppressWarnings = false;
+ }
+ }
if ((optionValue = optionsMap.get(OPTION_ReportMethodWithConstructorName)) != null) updateSeverity(MethodWithConstructorName, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportOverridingPackageDefaultMethod)) != null) updateSeverity(OverriddenPackageDefaultMethod, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportDeprecation)) != null) updateSeverity(UsingDeprecatedAPI, optionValue);
@@ -593,6 +617,7 @@
if ((optionValue = optionsMap.get(OPTION_ReportMissingOverrideAnnotation)) != null) updateSeverity(MissingOverrideAnnotation, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportMissingDeprecatedAnnotation)) != null) updateSeverity(MissingDeprecatedAnnotation, optionValue);
if ((optionValue = optionsMap.get(OPTION_ReportIncompleteEnumSwitch)) != null) updateSeverity(IncompleteEnumSwitch, optionValue);
+ if ((optionValue = optionsMap.get(OPTION_ReportUnhandledWarningToken)) != null) updateSeverity(UnhandledWarningToken, optionValue);
// Javadoc options
if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) {
@@ -605,7 +630,7 @@
if ((optionValue = optionsMap.get(OPTION_ReportInvalidJavadoc)) != null) {
updateSeverity(InvalidJavadoc, optionValue);
}
- if ((optionValue = optionsMap.get(OPTION_ReportInvalidJavadocTagsVisibility)) != null) {
+ if ( (optionValue = optionsMap.get(OPTION_ReportInvalidJavadocTagsVisibility)) != null) {
if (PUBLIC.equals(optionValue)) {
this.reportInvalidJavadocTagsVisibility = AccPublic;
} else if (PROTECTED.equals(optionValue)) {
@@ -752,7 +777,9 @@
buf.append("\n\t- annotation super interface: ").append(getSeverityString(AnnotationSuperInterface)); //$NON-NLS-1$
buf.append("\n\t- missing @Override annotation: ").append(getSeverityString(MissingOverrideAnnotation)); //$NON-NLS-1$
buf.append("\n\t- missing @Deprecated annotation: ").append(getSeverityString(MissingDeprecatedAnnotation)); //$NON-NLS-1$
- buf.append("\n\t- incomplete enum switch: ").append(getSeverityString(IncompleteEnumSwitch)); //$NON-NLS-1$
+ buf.append("\n\t- incomplete enum switch: ").append(getSeverityString(IncompleteEnumSwitch)); //$NON-NLS-1$
+ buf.append("\n\t- suppress warnings: ").append(this.suppressWarnings ? ENABLED : DISABLED); //$NON-NLS-1$
+ buf.append("\n\t- unhandled warning token: ").append(getSeverityString(UnhandledWarningToken)); //$NON-NLS-1$
return buf.toString();
}
@@ -797,4 +824,158 @@
}
return ""; // unknown version //$NON-NLS-1$
}
+
+ /**
+ * Return all warning option names for use as keys in compiler options maps.
+ * @return all warning option names
+ */
+ public static String[] warningOptionNames() {
+ String[] result = {
+ OPTION_ReportAnnotationSuperInterface,
+ OPTION_ReportAssertIdentifier,
+ OPTION_ReportAutoboxing,
+ OPTION_ReportDeprecation,
+ OPTION_ReportDiscouragedReference,
+ OPTION_ReportEmptyStatement,
+ OPTION_ReportEnumIdentifier,
+ OPTION_ReportFieldHiding,
+ OPTION_ReportFinalParameterBound,
+ OPTION_ReportFinallyBlockNotCompletingNormally,
+ OPTION_ReportForbiddenReference,
+ OPTION_ReportHiddenCatchBlock,
+ OPTION_ReportIncompatibleNonInheritedInterfaceMethod,
+ OPTION_ReportIncompleteEnumSwitch,
+ OPTION_ReportIndirectStaticAccess,
+ OPTION_ReportInvalidJavadoc,
+ OPTION_ReportLocalVariableHiding,
+ OPTION_ReportMethodWithConstructorName,
+ OPTION_ReportMissingDeprecatedAnnotation,
+ OPTION_ReportMissingJavadocComments,
+ OPTION_ReportMissingJavadocTags,
+ OPTION_ReportMissingOverrideAnnotation,
+ OPTION_ReportMissingSerialVersion,
+ OPTION_ReportNoEffectAssignment,
+ OPTION_ReportNoImplicitStringConversion,
+ OPTION_ReportNonExternalizedStringLiteral,
+ OPTION_ReportNonStaticAccessToStatic,
+ OPTION_ReportNullReference,
+ OPTION_ReportOverridingPackageDefaultMethod,
+ OPTION_ReportPossibleAccidentalBooleanAssignment,
+ OPTION_ReportSyntheticAccessEmulation,
+ OPTION_ReportTypeParameterHiding,
+ OPTION_ReportUncheckedTypeOperation,
+ OPTION_ReportUndocumentedEmptyBlock,
+ OPTION_ReportUnnecessaryElse,
+ OPTION_ReportUnnecessaryTypeCheck,
+ OPTION_ReportUnqualifiedFieldAccess,
+ OPTION_ReportUnusedDeclaredThrownException,
+ OPTION_ReportUnusedImport,
+ OPTION_ReportUnusedLocal,
+ OPTION_ReportUnusedParameter,
+ OPTION_ReportUnusedPrivateMember,
+ OPTION_ReportVarargsArgumentNeedCast,
+ OPTION_ReportUnhandledWarningToken,
+ };
+ return result;
+ }
+
+ public static String warningTokenFromIrritant(long irritant) {
+ int irritantInt = (int) irritant;
+ if (irritantInt == irritant) {
+ switch (irritantInt) {
+ case (int) (InvalidJavadoc | UsingDeprecatedAPI) :
+ case (int) UsingDeprecatedAPI :
+ return "deprecation"; //$NON-NLS-1$
+ case (int) FinallyBlockNotCompleting :
+ return "finally"; //$NON-NLS-1$
+ case (int) FieldHiding :
+ case (int) LocalVariableHiding :
+ case (int) MaskedCatchBlock :
+ return "hiding"; //$NON-NLS-1$
+ case (int) NonExternalizedString :
+ return "nls"; //$NON-NLS-1$
+ case (int) UnusedLocalVariable :
+ case (int) UnusedArgument :
+ case (int) UnusedPrivateMember:
+ case (int) UnusedDeclaredThrownException:
+ return "unused"; //$NON-NLS-1$
+ case (int) IndirectStaticAccess :
+ case (int) NonStaticAccessToStatic :
+ return "static-access"; //$NON-NLS-1$
+ case (int) AccessEmulation :
+ return "synthetic-access"; //$NON-NLS-1$
+ case (int) UnqualifiedFieldAccess :
+ return "unqualified-field-access"; //$NON-NLS-1$
+ case (int) UncheckedTypeOperation :
+ return "unchecked"; //$NON-NLS-1$
+ }
+ } else {
+ irritantInt = (int)(irritant >>> 32);
+ // TODO (olivier) remove contants once http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21540 is fixed
+ switch (irritantInt) {
+ case IntMissingSerialVersion :
+ return "serial"; //$NON-NLS-1$
+ case IntAutoBoxing :
+ return "boxing"; //$NON-NLS-1$
+ case IntTypeParameterHiding :
+ return "hiding"; //$NON-NLS-1$
+ case IntIncompleteEnumSwitch :
+ return "incomplete-switch"; //$NON-NLS-1$
+ case IntMissingDeprecatedAnnotation :
+ return "dep-ann"; //$NON-NLS-1$
+ }
+ }
+ return null;
+ }
+ public static long warningTokenToIrritant(String warningToken) {
+ if (warningToken == null || warningToken.length() == 0) return 0;
+ switch (warningToken.charAt(0)) {
+ case 'a' :
+ if ("all".equals(warningToken)) //$NON-NLS-1$
+ return 0xFFFFFFFFFFFFFFFFl; // suppress all warnings
+ break;
+ case 'b' :
+ if ("boxing".equals(warningToken)) //$NON-NLS-1$
+ return Autoboxing;
+ break;
+ case 'd' :
+ if ("deprecation".equals(warningToken)) //$NON-NLS-1$
+ return UsingDeprecatedAPI;
+ if ("dep-ann".equals(warningToken)) //$NON-NLS-1$
+ return MissingDeprecatedAnnotation;
+ break;
+ case 'f' :
+ if ("finally".equals(warningToken)) //$NON-NLS-1$
+ return FinallyBlockNotCompleting;
+ break;
+ case 'h' :
+ if ("hiding".equals(warningToken)) //$NON-NLS-1$
+ return FieldHiding | LocalVariableHiding | MaskedCatchBlock | TypeParameterHiding;
+ case 'i' :
+ if ("incomplete-switch".equals(warningToken)) //$NON-NLS-1$
+ return IncompleteEnumSwitch;
+ break;
+ case 'n' :
+ if ("nls".equals(warningToken)) //$NON-NLS-1$
+ return NonExternalizedString;
+ break;
+ case 's' :
+ if ("serial".equals(warningToken)) //$NON-NLS-1$
+ return MissingSerialVersion;
+ if ("static-access".equals(warningToken)) //$NON-NLS-1$
+ return IndirectStaticAccess | NonStaticAccessToStatic;
+ if ("synthetic-access".equals(warningToken)) //$NON-NLS-1$
+ return AccessEmulation;
+ break;
+ case 'u' :
+ if ("unused".equals(warningToken)) //$NON-NLS-1$
+ return UnusedLocalVariable | UnusedArgument | UnusedPrivateMember | UnusedDeclaredThrownException;
+ if ("unchecked".equals(warningToken)) //$NON-NLS-1$
+ return UncheckedTypeOperation;
+ if ("unqualified-field-access".equals(warningToken)) //$NON-NLS-1$
+ return UnqualifiedFieldAccess;
+ break;
+ }
+ return 0;
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
index 43baa94..53374fe 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
@@ -21,6 +21,6 @@
public interface ReferenceContext {
void abort(int abortLevel, IProblem problem);
CompilationResult compilationResult();
- void tagAsHavingErrors();
boolean hasErrors();
+ void tagAsHavingErrors();
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
index faccf47..6e0e788 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
@@ -36,10 +36,6 @@
this.tagBits |= type.tagBits & (HasTypeVariable | HasDirectWildcard);
}
-public int kind() {
- return ARRAY_TYPE;
-}
-
/**
* Collect the substitutes into a map for certain type variables inside the receiver type
* e.g. Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
@@ -70,10 +66,10 @@
* brakets leafUniqueKey
* p.X[][] --> [[Lp/X;
*/
-public char[] computeUniqueKey(boolean withAccessFlags) {
+public char[] computeUniqueKey(boolean isLeaf) {
char[] brackets = new char[dimensions];
for (int i = dimensions - 1; i >= 0; i--) brackets[i] = '[';
- return CharOperation.concat(brackets, this.leafComponentType.computeUniqueKey(false/*without access flags*/));
+ return CharOperation.concat(brackets, this.leafComponentType.computeUniqueKey(isLeaf));
}
/**
@@ -121,6 +117,31 @@
return this.environment;
}
+/**
+ * Find supertype which erases to a given type, or null if not found
+ */
+public TypeBinding findSuperTypeWithSameErasure(TypeBinding otherType) {
+
+ if (this == otherType) return this;
+ int otherDim = otherType.dimensions();
+ if (this.dimensions != otherDim) {
+ switch(otherType.id) {
+ case T_JavaLangObject :
+ case T_JavaIoSerializable :
+ case T_JavaLangCloneable :
+ return otherType;
+ }
+ if (otherDim < this.dimensions & otherType.leafComponentType().id == T_JavaLangObject) {
+ return otherType; // X[][] has Object[] as an implicit supertype
+ }
+ return null;
+ }
+ if (!(this.leafComponentType instanceof ReferenceBinding)) return null;
+ TypeBinding leafSuperType = ((ReferenceBinding)this.leafComponentType).findSuperTypeWithSameErasure(otherType.leafComponentType());
+ if (leafSuperType == null) return null;
+ return environment().createArrayType(leafSuperType, this.dimensions);
+}
+
public char[] genericTypeSignature() {
if (this.genericTypeSignature == null) {
@@ -134,33 +155,48 @@
public PackageBinding getPackage() {
return leafComponentType.getPackage();
}
+
public int hashCode() {
return this.leafComponentType == null ? super.hashCode() : this.leafComponentType.hashCode();
}
+
/* Answer true if the receiver type can be assigned to the argument type (right)
*/
-public boolean isCompatibleWith(TypeBinding right) {
- if (this == right)
+public boolean isCompatibleWith(TypeBinding otherType) {
+ if (this == otherType)
return true;
- switch (right.kind()) {
+ switch (otherType.kind()) {
case Binding.ARRAY_TYPE :
- ArrayBinding rightArray = (ArrayBinding) right;
- if (rightArray.leafComponentType.isBaseType())
+ ArrayBinding otherArray = (ArrayBinding) otherType;
+ if (otherArray.leafComponentType.isBaseType())
return false; // relying on the fact that all equal arrays are identical
- if (dimensions == rightArray.dimensions)
- return leafComponentType.isCompatibleWith(rightArray.leafComponentType);
- if (dimensions < rightArray.dimensions)
+ if (dimensions == otherArray.dimensions)
+ return leafComponentType.isCompatibleWith(otherArray.leafComponentType);
+ if (dimensions < otherArray.dimensions)
return false; // cannot assign 'String[]' into 'Object[][]' but can assign 'byte[][]' into 'Object[]'
break;
case Binding.BASE_TYPE :
return false;
case Binding.WILDCARD_TYPE :
- return ((WildcardBinding) right).boundCheck(this);
+ return ((WildcardBinding) otherType).boundCheck(this);
+
+ case Binding.TYPE_PARAMETER :
+ // check compatibility with capture of ? super X
+ if (otherType.isCapture()) {
+ CaptureBinding otherCapture = (CaptureBinding) otherType;
+ TypeBinding otherLowerBound;
+ if ((otherLowerBound = otherCapture.lowerBound) != null) {
+ if (!otherLowerBound.isArrayType()) return false;
+ return this.isCompatibleWith(otherLowerBound);
+ }
+ }
+ return false;
+
}
//Check dimensions - Java does not support explicitly sized dimensions for types.
//However, if it did, the type checking support would go here.
- switch (right.leafComponentType().id) {
+ switch (otherType.leafComponentType().id) {
case T_JavaLangObject :
case T_JavaLangCloneable :
case T_JavaIoSerializable :
@@ -169,6 +205,10 @@
return false;
}
+public int kind() {
+ return ARRAY_TYPE;
+}
+
public TypeBinding leafComponentType(){
return leafComponentType;
}
@@ -177,7 +217,6 @@
* Answer the problem id associated with the receiver.
* NoError if the receiver is a valid binding.
*/
-
public int problemId() {
return leafComponentType.problemId();
}
@@ -221,7 +260,7 @@
}
public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
if (this.leafComponentType == unresolvedType) {
- this.leafComponentType = resolvedType.isGenericType() ? env.createRawType(resolvedType, resolvedType.enclosingType()) : resolvedType;
+ this.leafComponentType = env.convertToRawType(resolvedType);
this.tagBits |= this.leafComponentType.tagBits & (HasTypeVariable | HasDirectWildcard);
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
index 96f3d51..d4d76f6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
@@ -26,7 +26,7 @@
/**
* int -> I
*/
- public char[] computeUniqueKey(boolean withAccessFlags) {
+ public char[] computeUniqueKey(boolean isLeaf) {
return constantPoolName();
}
@@ -136,7 +136,13 @@
return false;
}
}
-
+ /**
+ * T_null is acting as an unchecked exception
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isUncheckedException(boolean)
+ */
+ public boolean isUncheckedException(boolean includeSupertype) {
+ return this == NullBinding;
+ }
public static final boolean isWidening(int left, int right) {
//can "left" store a "right" using some widening conversion
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index 9cbcb0d..9f8ff61 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -54,8 +54,8 @@
if (type.isWildcard())
return ((WildcardBinding) type).resolve();
- if (convertGenericToRawType && type.isGenericType()) // raw reference to generic ?
- return environment.createRawType(type, type.enclosingType());
+ if (convertGenericToRawType) // raw reference to generic ?
+ return (ReferenceBinding) environment.convertToRawType(type);
return type;
}
public static TypeBinding resolveType(TypeBinding type, LookupEnvironment environment, ParameterizedTypeBinding parameterizedType, int rank) {
@@ -77,7 +77,7 @@
case Binding.GENERIC_TYPE :
if (parameterizedType == null) // raw reference to generic ?
- return environment.createRawType((ReferenceBinding) type, type.enclosingType());
+ return environment.convertToRawType(type);
break;
default:
@@ -108,7 +108,7 @@
this.fPackage = packageBinding;
this.fileName = binaryType.getFileName();
- char[] typeSignature = environment.options.sourceLevel >= ClassFileConstants.JDK1_5 ? binaryType.getGenericSignature() : null;
+ char[] typeSignature = environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_5 ? binaryType.getGenericSignature() : null;
this.typeVariables = typeSignature != null && typeSignature.length > 0 && typeSignature[0] == '<'
? null // is initialized in cachePartsFrom (called from LookupEnvironment.createBinaryTypeFrom())... must set to null so isGenericType() answers true
: NoTypeVariables;
@@ -134,6 +134,18 @@
} else if (binaryType.isMember()) {
this.tagBits |= MemberTypeMask;
}
+ // need enclosing type to access type variables
+ char[] enclosingTypeName = binaryType.getEnclosingTypeName();
+ if (enclosingTypeName != null) {
+ // attempt to find the enclosing type if it exists in the cache (otherwise - resolve it when requested)
+ this.enclosingType = environment.getTypeFromConstantPoolName(enclosingTypeName, 0, -1, true); // pretend parameterized to avoid raw
+ this.tagBits |= MemberTypeMask; // must be a member type not a top-level or local type
+ this.tagBits |= HasUnresolvedEnclosingType;
+ if (this.enclosingType().isStrictfp())
+ this.modifiers |= AccStrictfp;
+ if (this.enclosingType().isDeprecated())
+ this.modifiers |= AccDeprecatedImplicitly;
+ }
}
public FieldBinding[] availableFields() {
@@ -178,20 +190,7 @@
this.typeVariables = NoTypeVariables;
this.superInterfaces = NoSuperInterfaces;
- // need enclosing type to access type variables
- char[] enclosingTypeName = binaryType.getEnclosingTypeName();
- if (enclosingTypeName != null) {
- // attempt to find the enclosing type if it exists in the cache (otherwise - resolve it when requested)
- this.enclosingType = environment.getTypeFromConstantPoolName(enclosingTypeName, 0, -1, true); // pretend parameterized to avoid raw
- this.tagBits |= MemberTypeMask; // must be a member type not a top-level or local type
- this.tagBits |= HasUnresolvedEnclosingType;
- if (this.enclosingType().isStrictfp())
- this.modifiers |= AccStrictfp;
- if (this.enclosingType().isDeprecated())
- this.modifiers |= AccDeprecatedImplicitly;
- }
-
- long sourceLevel = environment.options.sourceLevel;
+ long sourceLevel = environment.globalOptions.sourceLevel;
char[] typeSignature = null;
if (sourceLevel >= ClassFileConstants.JDK1_5) {
typeSignature = binaryType.getGenericSignature();
@@ -293,6 +292,8 @@
field.tagBits |= binaryField.getTagBits();
if (isViewedAsDeprecated && !field.isDeprecated())
field.modifiers |= AccDeprecatedImplicitly;
+ if (fieldSignature != null)
+ field.modifiers |= AccGenericSignature;
this.fields[i] = field;
}
}
@@ -353,6 +354,7 @@
if (!method.isConstructor())
returnType = environment.getTypeFromSignature(methodDescriptor, index + 1, -1, false, this); // index is currently pointing at the ')'
} else {
+ methodModifiers |= AccGenericSignature;
// MethodTypeSignature = ParameterPart(optional) '(' TypeSignatures ')' return_typeSignature ['^' TypeSignature (optional)]
SignatureWrapper wrapper = new SignatureWrapper(methodSignature);
if (wrapper.signature[wrapper.start] == '<') {
@@ -794,72 +796,75 @@
return this.typeVariables;
}
public String toString() {
- String s = ""; //$NON-NLS-1$
+ StringBuffer buffer = new StringBuffer();
- if (isDeprecated()) s += "deprecated "; //$NON-NLS-1$
- if (isPublic()) s += "public "; //$NON-NLS-1$
- if (isProtected()) s += "protected "; //$NON-NLS-1$
- if (isPrivate()) s += "private "; //$NON-NLS-1$
- if (isAbstract() && isClass()) s += "abstract "; //$NON-NLS-1$
- if (isStatic() && isNestedType()) s += "static "; //$NON-NLS-1$
- if (isFinal()) s += "final "; //$NON-NLS-1$
+ if (isDeprecated()) buffer.append("deprecated "); //$NON-NLS-1$
+ if (isPublic()) buffer.append("public "); //$NON-NLS-1$
+ if (isProtected()) buffer.append("protected "); //$NON-NLS-1$
+ if (isPrivate()) buffer.append("private "); //$NON-NLS-1$
+ if (isAbstract() && isClass()) buffer.append("abstract "); //$NON-NLS-1$
+ if (isStatic() && isNestedType()) buffer.append("static "); //$NON-NLS-1$
+ if (isFinal()) buffer.append("final "); //$NON-NLS-1$
- s += isInterface() ? "interface " : "class "; //$NON-NLS-1$ //$NON-NLS-2$
- s += (compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED TYPE"; //$NON-NLS-1$
+ if (isEnum()) buffer.append("enum "); //$NON-NLS-1$
+ else if (isAnnotationType()) buffer.append("@interface "); //$NON-NLS-1$
+ else if (isClass()) buffer.append("class "); //$NON-NLS-1$
+ else buffer.append("interface "); //$NON-NLS-1$
+ buffer.append((compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED TYPE"); //$NON-NLS-1$
- s += "\n\textends "; //$NON-NLS-1$
- s += (superclass != null) ? superclass.debugName() : "NULL TYPE"; //$NON-NLS-1$
+ buffer.append("\n\textends "); //$NON-NLS-1$
+ buffer.append((superclass != null) ? superclass.debugName() : "NULL TYPE"); //$NON-NLS-1$
if (superInterfaces != null) {
if (superInterfaces != NoSuperInterfaces) {
- s += "\n\timplements : "; //$NON-NLS-1$
+ buffer.append("\n\timplements : "); //$NON-NLS-1$
for (int i = 0, length = superInterfaces.length; i < length; i++) {
if (i > 0)
- s += ", "; //$NON-NLS-1$
- s += (superInterfaces[i] != null) ? superInterfaces[i].debugName() : "NULL TYPE"; //$NON-NLS-1$
+ buffer.append(", "); //$NON-NLS-1$
+ buffer.append((superInterfaces[i] != null) ? superInterfaces[i].debugName() : "NULL TYPE"); //$NON-NLS-1$
}
}
} else {
- s += "NULL SUPERINTERFACES"; //$NON-NLS-1$
+ buffer.append("NULL SUPERINTERFACES"); //$NON-NLS-1$
}
if (enclosingType != null) {
- s += "\n\tenclosing type : "; //$NON-NLS-1$
- s += enclosingType.debugName();
+ buffer.append("\n\tenclosing type : "); //$NON-NLS-1$
+ buffer.append(enclosingType.debugName());
}
if (fields != null) {
if (fields != NoFields) {
- s += "\n/* fields */"; //$NON-NLS-1$
+ buffer.append("\n/* fields */"); //$NON-NLS-1$
for (int i = 0, length = fields.length; i < length; i++)
- s += (fields[i] != null) ? "\n" + fields[i].toString() : "\nNULL FIELD"; //$NON-NLS-1$ //$NON-NLS-2$
+ buffer.append((fields[i] != null) ? "\n" + fields[i].toString() : "\nNULL FIELD"); //$NON-NLS-1$ //$NON-NLS-2$
}
} else {
- s += "NULL FIELDS"; //$NON-NLS-1$
+ buffer.append("NULL FIELDS"); //$NON-NLS-1$
}
if (methods != null) {
if (methods != NoMethods) {
- s += "\n/* methods */"; //$NON-NLS-1$
+ buffer.append("\n/* methods */"); //$NON-NLS-1$
for (int i = 0, length = methods.length; i < length; i++)
- s += (methods[i] != null) ? "\n" + methods[i].toString() : "\nNULL METHOD"; //$NON-NLS-1$ //$NON-NLS-2$
+ buffer.append((methods[i] != null) ? "\n" + methods[i].toString() : "\nNULL METHOD"); //$NON-NLS-1$ //$NON-NLS-2$
}
} else {
- s += "NULL METHODS"; //$NON-NLS-1$
+ buffer.append("NULL METHODS"); //$NON-NLS-1$
}
if (memberTypes != null) {
if (memberTypes != NoMemberTypes) {
- s += "\n/* members */"; //$NON-NLS-1$
+ buffer.append("\n/* members */"); //$NON-NLS-1$
for (int i = 0, length = memberTypes.length; i < length; i++)
- s += (memberTypes[i] != null) ? "\n" + memberTypes[i].toString() : "\nNULL TYPE"; //$NON-NLS-1$ //$NON-NLS-2$
+ buffer.append((memberTypes[i] != null) ? "\n" + memberTypes[i].toString() : "\nNULL TYPE"); //$NON-NLS-1$ //$NON-NLS-2$
}
} else {
- s += "NULL MEMBER TYPES"; //$NON-NLS-1$
+ buffer.append("NULL MEMBER TYPES"); //$NON-NLS-1$
}
- s += "\n\n\n"; //$NON-NLS-1$
- return s;
+ buffer.append("\n\n\n"); //$NON-NLS-1$
+ return buffer.toString();
}
MethodBinding[] unResolvedMethods() { // for the MethodVerifier so it doesn't resolve types
return methods;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
index 389003f..e7bc26b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
@@ -30,9 +30,6 @@
public static final int GENERIC_TYPE = TYPE | ASTNode.Bit12;
public static final int TYPE_PARAMETER = TYPE | ASTNode.Bit13;
- // TODO (jerome) change to true to fix https://bugs.eclipse.org/bugs/show_bug.cgi?id=90392
- public static boolean USE_ACCESS_FLAGS_IN_BINDING_KEY = false;
-
/* API
* Answer the receiver's binding type from Binding.BindingID.
*
@@ -45,13 +42,13 @@
* Returns null if binding is not a TypeBinding, a MethodBinding, a FieldBinding or a PackageBinding.
*/
public char[] computeUniqueKey() {
- return computeUniqueKey(USE_ACCESS_FLAGS_IN_BINDING_KEY/*without access flags*/);
+ return computeUniqueKey(true/*leaf*/);
}
/*
* Computes a key that uniquely identifies this binding. Optinaly include access flags.
* Returns null if binding is not a TypeBinding, a MethodBinding, a FieldBinding or a PackageBinding.
*/
- public char[] computeUniqueKey(boolean withAccessFlags) {
+ public char[] computeUniqueKey(boolean isLeaf) {
return null;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index 4562dac..bd18bac 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -152,8 +152,7 @@
if (methodScope.isStatic != binding.isStatic())
return false;
return methodScope.isInsideInitializer() // inside initializer
- || ((AbstractMethodDeclaration) methodScope.referenceContext)
- .isInitializationMethod(); // inside constructor or clinit
+ || ((AbstractMethodDeclaration) methodScope.referenceContext).isInitializationMethod(); // inside constructor or clinit
}
String basicToString(int tab) {
String newLine = "\n"; //$NON-NLS-1$
@@ -235,7 +234,7 @@
// could be optimized out, but does need to preserve unread variables ?
if (!generateCurrentLocalVar) {
- if (local.declaration != null && environment().options.preserveAllLocalVariables) {
+ if (local.declaration != null && compilerOptions().preserveAllLocalVariables) {
generateCurrentLocalVar = true; // force it to be preserved in the generated code
local.useFlag = LocalVariableBinding.USED;
}
@@ -320,7 +319,7 @@
*/
public final ReferenceBinding findLocalType(char[] name) {
- long compliance = environment().options.complianceLevel;
+ long compliance = compilerOptions().complianceLevel;
for (int i = 0, length = subscopeCount; i < length; i++) {
if (subscopes[i] instanceof ClassScope) {
LocalTypeBinding sourceType = (LocalTypeBinding)((ClassScope) subscopes[i]).referenceContext.binding;
@@ -402,6 +401,7 @@
// must be a type if its the last name, otherwise we have no idea if its a package or type
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null,
NotFound);
}
return new ProblemBinding(
@@ -412,6 +412,7 @@
if (!binding.isValidBinding())
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
binding.problemId());
if (!((ReferenceBinding) binding).canBeSeenBy(this))
return new ProblemReferenceBinding(
@@ -426,10 +427,12 @@
// It is illegal to request a PACKAGE from this method.
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null,
NotFound);
}
// know binding is now a ReferenceBinding
+ binding = environment().convertToRawType((ReferenceBinding) binding);
while (currentIndex < length) {
ReferenceBinding typeBinding = (ReferenceBinding) binding;
char[] nextName = compoundName[currentIndex++];
@@ -438,7 +441,7 @@
if ((mask & Binding.FIELD) != 0 && (binding = findField(typeBinding, nextName, invocationSite, true /*resolve*/)) != null) {
if (!binding.isValidBinding())
return new ProblemFieldBinding(
- ((FieldBinding) binding).declaringClass,
+ (FieldBinding)binding,
CharOperation.subarray(compoundName, 0, currentIndex),
binding.problemId());
break; // binding is now a field
@@ -458,6 +461,7 @@
if (!binding.isValidBinding())
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
binding.problemId());
}
if ((mask & Binding.FIELD) != 0 && (binding instanceof FieldBinding)) {
@@ -465,7 +469,7 @@
FieldBinding field = (FieldBinding) binding;
if (!field.isStatic())
return new ProblemFieldBinding(
- field.declaringClass,
+ field,
CharOperation.subarray(compoundName, 0, currentIndex),
NonStaticReferenceInStaticContext);
return binding;
@@ -505,6 +509,7 @@
// must be a type if its the last name, otherwise we have no idea if its a package or type
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null,
NotFound);
}
return new ProblemBinding(
@@ -515,6 +520,7 @@
if (!binding.isValidBinding())
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
binding.problemId());
if (!((ReferenceBinding) binding).canBeSeenBy(this))
return new ProblemReferenceBinding(
@@ -534,12 +540,12 @@
if ((binding = findField(typeBinding, nextName, invocationSite, true /*resolve*/)) != null) {
if (!binding.isValidBinding())
return new ProblemFieldBinding(
- ((FieldBinding) binding).declaringClass,
+ (FieldBinding) binding,
CharOperation.subarray(compoundName, 0, currentIndex),
binding.problemId());
if (!((FieldBinding) binding).isStatic())
return new ProblemFieldBinding(
- ((FieldBinding) binding).declaringClass,
+ (FieldBinding) binding,
CharOperation.subarray(compoundName, 0, currentIndex),
NonStaticReferenceInStaticContext);
break foundField; // binding is now a field
@@ -552,6 +558,7 @@
if (!binding.isValidBinding())
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
binding.problemId());
}
return binding;
@@ -645,7 +652,7 @@
// use 'this' if possible
if (!currentMethodScope.isStatic && !currentMethodScope.isConstructorCall) {
- if (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeErasingTo(targetEnclosingType) != null)) {
+ if (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeWithSameErasure(targetEnclosingType) != null)) {
return EmulationPathToImplicitThis; // implicit this is good enough
}
}
@@ -665,7 +672,7 @@
// reject allocation and super constructor call
if (denyEnclosingArgInConstructorCall
&& currentMethodScope.isConstructorCall
- && (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeErasingTo(targetEnclosingType) != null))) {
+ && (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeWithSameErasure(targetEnclosingType) != null))) {
return NoEnclosingInstanceInConstructorCall;
}
return new Object[] { syntheticArg };
@@ -684,7 +691,7 @@
if (enclosingArgument != null) {
FieldBinding syntheticField = sourceType.getSyntheticField(enclosingArgument);
if (syntheticField != null) {
- if (syntheticField.type == targetEnclosingType || (!onlyExactMatch && ((ReferenceBinding)syntheticField.type).findSuperTypeErasingTo(targetEnclosingType) != null))
+ if (syntheticField.type == targetEnclosingType || (!onlyExactMatch && ((ReferenceBinding)syntheticField.type).findSuperTypeWithSameErasure(targetEnclosingType) != null))
return new Object[] { syntheticField };
}
}
@@ -717,7 +724,7 @@
//done?
if (currentType == targetEnclosingType
- || (!onlyExactMatch && currentType.findSuperTypeErasingTo(targetEnclosingType) != null)) break;
+ || (!onlyExactMatch && currentType.findSuperTypeWithSameErasure(targetEnclosingType) != null)) break;
if (currentMethodScope != null) {
currentMethodScope = currentMethodScope.enclosingMethodScope();
@@ -741,7 +748,7 @@
currentType = currentEnclosingType;
}
if (currentType == targetEnclosingType
- || (!onlyExactMatch && currentType.findSuperTypeErasingTo(targetEnclosingType) != null)) {
+ || (!onlyExactMatch && currentType.findSuperTypeWithSameErasure(targetEnclosingType) != null)) {
return path;
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
index 49db10a..226704d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
@@ -18,46 +18,38 @@
public TypeBinding lowerBound;
public WildcardBinding wildcard;
- public CaptureBinding(WildcardBinding wildcard) {
+ /* information to compute unique binding key */
+ public ReferenceBinding sourceType;
+ public int position;
+
+ public CaptureBinding(WildcardBinding wildcard, ReferenceBinding sourceType, int position) {
super(WILDCARD_CAPTURE_NAME, null, 0);
this.wildcard = wildcard;
this.modifiers = AccPublic | AccGenericSignature; // treat capture as public
this.fPackage = wildcard.fPackage;
-
- TypeVariableBinding wildcardVariable = wildcard.typeVariable();
- switch (wildcard.boundKind) {
- case Wildcard.EXTENDS :
- this.superclass = wildcard.superclass();
- this.firstBound = wildcard.bound;
- ReferenceBinding[] wildcardInterfaces = wildcard.superInterfaces();
- if (wildcardInterfaces == NoSuperInterfaces) {
- this.superInterfaces = NoSuperInterfaces;
- } else {
- this.superInterfaces = Scope.greaterLowerBound(wildcardInterfaces);
- }
- if ((wildcard.bound.tagBits & HasTypeVariable) == 0)
- this.tagBits &= ~HasTypeVariable;
- break;
- case Wildcard.UNBOUND :
- this.superclass = wildcardVariable.superclass();
- this.superInterfaces = wildcardVariable.superInterfaces();
- this.tagBits &= ~HasTypeVariable;
- break;
- case Wildcard.SUPER :
- this.superclass = wildcardVariable.superclass();
- if (wildcardVariable.firstBound == this.superclass || wildcard.bound == this.superclass) {
- this.firstBound = this.superclass;
- }
- this.superInterfaces = wildcardVariable.superInterfaces();
- this.lowerBound = wildcard.bound;
- if ((wildcard.bound.tagBits & HasTypeVariable) == 0)
- this.tagBits &= ~HasTypeVariable;
- break;
- }
+ this.sourceType = sourceType;
+ this.position = position;
}
- public char[] computeUniqueKey(boolean withAccessFlags) {
- return CharOperation.concat(WILDCARD_CAPTURE, this.wildcard.computeUniqueKey(withAccessFlags));
+ /*
+ * sourceTypeKey ! wildcardKey position semi-colon
+ * p.X { capture of ? } --> !*123; (Lp/X; in declaring type except if leaf)
+ * p.X { capture of ? extends p.Y } --> !+Lp/Y;123; (Lp/X; in declaring type except if leaf)
+ */
+ public char[] computeUniqueKey(boolean isLeaf) {
+ StringBuffer buffer = new StringBuffer();
+ if (isLeaf) {
+ buffer.append(this.sourceType.computeUniqueKey(false/*not a leaf*/));
+ buffer.append('&');
+ }
+ buffer.append(WILDCARD_CAPTURE);
+ buffer.append(this.wildcard.computeUniqueKey(false/*not a leaf*/));
+ buffer.append(this.position);
+ buffer.append(';');
+ int length = buffer.length();
+ char[] uniqueKey = new char[length];
+ buffer.getChars(0, length, uniqueKey, 0);
+ return uniqueKey;
}
public String debugName() {
@@ -73,6 +65,71 @@
}
return this.genericTypeSignature;
}
+
+ /**
+ * Initialize capture bounds using substituted supertypes
+ * e.g. given X<U, V extends X<U, V>>, capture(X<E,?>) = X<E,capture>, where capture extends X<E,capture>
+ */
+ public void initializeBounds(ParameterizedTypeBinding capturedParameterizedType) {
+ TypeVariableBinding wildcardVariable = wildcard.typeVariable();
+ ReferenceBinding originalVariableSuperclass = wildcardVariable.superclass;
+ ReferenceBinding substitutedVariableSuperclass = (ReferenceBinding) Scope.substitute(capturedParameterizedType, originalVariableSuperclass);
+ // prevent cyclic capture: given X<T>, capture(X<? extends T> could yield a circular type
+ if (substitutedVariableSuperclass == this) substitutedVariableSuperclass = originalVariableSuperclass;
+
+ ReferenceBinding[] originalVariableInterfaces = wildcardVariable.superInterfaces();
+ ReferenceBinding[] substitutedVariableInterfaces = Scope.substitute(capturedParameterizedType, originalVariableInterfaces);
+ if (substitutedVariableInterfaces != originalVariableInterfaces) {
+ // prevent cyclic capture: given X<T>, capture(X<? extends T> could yield a circular type
+ for (int i = 0, length = substitutedVariableInterfaces.length; i < length; i++) {
+ if (substitutedVariableInterfaces[i] == this) substitutedVariableInterfaces[i] = originalVariableInterfaces[i];
+ }
+ }
+ // no substitution for wildcard bound (only formal bounds from type variables are to be substituted: 104082)
+ TypeBinding originalWildcardBound = wildcard.bound;
+ // prevent cyclic capture: given X<T>, capture(X<? extends T> could yield a circular type
+// TypeBinding substitutedWildcardBound = originalWildcardBound == null ? null : Scope.substitute(capturedParameterizedType, originalWildcardBound);
+// if (substitutedWildcardBound == this) substitutedWildcardBound = originalWildcardBound;
+
+ switch (wildcard.boundKind) {
+ case Wildcard.EXTENDS :
+ if (wildcard.bound.isInterface()) {
+ this.superclass = substitutedVariableSuperclass;
+ // merge wildcard bound into variable superinterfaces using glb
+ if (substitutedVariableInterfaces == NoSuperInterfaces) {
+ this.superInterfaces = new ReferenceBinding[] { (ReferenceBinding) originalWildcardBound };
+ } else {
+ int length = substitutedVariableInterfaces.length;
+ System.arraycopy(substitutedVariableInterfaces, 0, substitutedVariableInterfaces = new ReferenceBinding[length+1], 1, length);
+ substitutedVariableInterfaces[0] = (ReferenceBinding) originalWildcardBound;
+ this.superInterfaces = Scope.greaterLowerBound(substitutedVariableInterfaces);
+ }
+ } else {
+ // per construction the wildcard bound is a subtype of variable superclass
+ this.superclass = wildcard.bound.isArrayType() ? substitutedVariableSuperclass : (ReferenceBinding)originalWildcardBound;
+ this.superInterfaces = substitutedVariableInterfaces;
+ }
+ this.firstBound = originalWildcardBound;
+ if ((originalWildcardBound.tagBits & HasTypeVariable) == 0)
+ this.tagBits &= ~HasTypeVariable;
+ break;
+ case Wildcard.UNBOUND :
+ this.superclass = substitutedVariableSuperclass;
+ this.superInterfaces = substitutedVariableInterfaces;
+ this.tagBits &= ~HasTypeVariable;
+ break;
+ case Wildcard.SUPER :
+ this.superclass = substitutedVariableSuperclass;
+ if (wildcardVariable.firstBound == substitutedVariableSuperclass || originalWildcardBound == substitutedVariableSuperclass) {
+ this.firstBound = substitutedVariableSuperclass;
+ }
+ this.superInterfaces = substitutedVariableInterfaces;
+ this.lowerBound = originalWildcardBound;
+ if ((originalWildcardBound.tagBits & HasTypeVariable) == 0)
+ this.tagBits &= ~HasTypeVariable;
+ break;
+ }
+ }
/**
* @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isCapture()
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
index b24595d..c58b20b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -10,11 +10,14 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
+import java.util.*;
+
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
@@ -26,8 +29,9 @@
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
public class ClassScope extends Scope {
+
public TypeDeclaration referenceContext;
- private TypeReference superTypeReference;
+ public TypeReference superTypeReference;
private final static char[] IncompleteHierarchy = new char[] {'h', 'a', 's', ' ', 'i', 'n', 'c', 'o', 'n', 's', 'i', 's', 't', 'e', 'n', 't', ' ', 'h', 'i', 'e', 'r', 'a', 'r', 'c', 'h', 'y'};
@@ -334,7 +338,7 @@
TypeParameter[] typeParameters = referenceContext.typeParameters;
// do not construct type variables if source < 1.5
- if (typeParameters == null || environment().options.sourceLevel < ClassFileConstants.JDK1_5) {
+ if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) {
sourceType.typeVariables = NoTypeVariables;
return;
}
@@ -356,9 +360,8 @@
ReferenceBinding enclosingType = sourceType.enclosingType();
boolean isMemberType = sourceType.isMemberType();
if (isMemberType) {
+ modifiers |= (enclosingType.modifiers & (AccGenericSignature|AccStrictfp));
// checks for member types before local types to catch local members
- if (enclosingType.isStrictfp())
- modifiers |= AccStrictfp;
if (enclosingType.isInterface())
modifiers |= AccPublic;
if (sourceType.isEnum()) {
@@ -466,9 +469,36 @@
problemReporter().illegalModifierForEnum(sourceType);
}
-// what about inherited interface methods?
- if ((referenceContext.bits & ASTNode.HasAbstractMethods) != 0)
+ // what about inherited interface methods?
+ if ((referenceContext.bits & ASTNode.HasAbstractMethods) != 0) {
modifiers |= AccAbstract;
+ } else if (!sourceType.isAnonymousType()) {
+ // body of enum constant must implement any inherited abstract methods
+ // enum type needs to implement abstract methods if one of its constants does not supply a body
+ checkAbstractEnum: {
+ TypeDeclaration typeDeclaration = this.referenceContext;
+ FieldDeclaration[] fields = typeDeclaration.fields;
+ int fieldsLength = fields == null ? 0 : fields.length;
+ if (fieldsLength == 0) break checkAbstractEnum; // has no constants so must implement the method itself
+ AbstractMethodDeclaration[] methods = typeDeclaration.methods;
+ int methodsLength = methods == null ? 0 : methods.length;
+ // TODO (kent) cannot tell that the superinterfaces are empty or that their methods are implemented
+ boolean definesAbstractMethod = typeDeclaration.superInterfaces != null;
+ for (int i = 0; i < methodsLength && !definesAbstractMethod; i++)
+ definesAbstractMethod = methods[i].isAbstract();
+ if (!definesAbstractMethod) break checkAbstractEnum; // all methods have bodies
+ for (int i = 0; i < fieldsLength; i++) {
+ FieldDeclaration fieldDecl = fields[i];
+ if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT)
+ if (!(fieldDecl.initialization instanceof QualifiedAllocationExpression))
+ break checkAbstractEnum;
+ }
+ // tag this enum as abstract since an abstract method must be implemented AND all enum constants define an anonymous body
+ // as a result, each of its anonymous constants will see it as abstract and must implement each inherited abstract method
+ modifiers |= AccAbstract;
+ }
+ }
+ modifiers |= AccFinal;
} else {
// detect abnormal cases for classes
if (isMemberType) { // includes member types defined inside local types
@@ -566,6 +596,8 @@
// set the modifiers
int implicitValue = AccPublic | AccStatic | AccFinal | AccEnum;
+ if (fieldDecl.initialization instanceof QualifiedAllocationExpression)
+ declaringClass.modifiers &= ~AccFinal;
fieldBinding.modifiers|= implicitValue;
return;
}
@@ -660,7 +692,7 @@
} while ((currentType = currentType.superclass()) != null && (currentType.tagBits & HasNoMemberTypes) == 0);
}
// Perform deferred bound checks for parameterized type references (only done after hierarchy is connected)
- private void checkParameterizedTypeBounds() {
+ public void checkParameterizedTypeBounds() {
TypeReference superclass = referenceContext.superclass;
if (superclass != null) {
superclass.checkBounds(this);
@@ -677,6 +709,12 @@
typeParameters[i].checkBounds(this);
}
}
+ // propagate to member types
+ ReferenceBinding[] memberTypes = referenceContext.binding.memberTypes;
+ if (memberTypes != null && memberTypes != NoMemberTypes) {
+ for (int i = 0, size = memberTypes.length; i < size; i++)
+ ((SourceTypeBinding) memberTypes[i]).scope.checkParameterizedTypeBounds();
+ }
}
private void connectMemberTypes() {
@@ -710,7 +748,7 @@
return true; // do not propagate Object's hierarchy problems down to every subtype
}
if (referenceContext.superclass == null) {
- if (sourceType.isEnum() && environment().options.sourceLevel >= JDK1_5) // do not connect if source < 1.5 as enum already got flagged as syntax error
+ if (sourceType.isEnum() && compilerOptions().sourceLevel >= JDK1_5) // do not connect if source < 1.5 as enum already got flagged as syntax error
return connectEnumSuperclass();
sourceType.superclass = getJavaLangObject();
return !detectHierarchyCycle(sourceType, sourceType.superclass, null);
@@ -756,12 +794,12 @@
return false; // cannot reach here as AbortCompilation is thrown
}
// check argument type compatibility
- ParameterizedTypeBinding superType = createParameterizedType(rootEnumType, new TypeBinding[]{ sourceType } , null);
+ ParameterizedTypeBinding superType = environment().createParameterizedType(rootEnumType, new TypeBinding[]{ environment().convertToRawType(sourceType) } , null);
sourceType.superclass = superType;
- // bound check
+ // bound check (in case of bogus definition of Enum type)
if (refTypeVariables[0].boundCheck(superType, sourceType) != TypeConstants.OK) {
problemReporter().typeMismatchError(rootEnumType, refTypeVariables[0], sourceType, null);
- }
+ }
return !foundCycle;
}
@@ -779,7 +817,7 @@
SourceTypeBinding sourceType = referenceContext.binding;
sourceType.superInterfaces = NoSuperInterfaces;
if (referenceContext.superInterfaces == null) {
- if (sourceType.isAnnotationType() && environment().options.sourceLevel >= JDK1_5) { // do not connect if source < 1.5 as annotation already got flagged as syntax error) {
+ if (sourceType.isAnnotationType() && compilerOptions().sourceLevel >= JDK1_5) { // do not connect if source < 1.5 as annotation already got flagged as syntax error) {
ReferenceBinding annotationType = getJavaLangAnnotationAnnotation();
boolean foundCycle = detectHierarchyCycle(sourceType, annotationType, null);
sourceType.superInterfaces = new ReferenceBinding[] { annotationType };
@@ -803,10 +841,11 @@
continue nextInterface;
}
superInterfaceRef.resolvedType = superInterface; // hold onto the problem type
+ // check for simple interface collisions
// Check for a duplicate interface once the name is resolved, otherwise we may be confused (ie : a.b.I and c.d.I)
- for (int k = 0; k < count; k++) {
- if (interfaceBindings[k].erasure() == superInterface.erasure()) {
- problemReporter().duplicateSuperinterface(sourceType, referenceContext, (ReferenceBinding) superInterface.erasure());
+ for (int j = 0; j < i; j++) {
+ if (interfaceBindings[j] == superInterface) {
+ problemReporter().duplicateSuperinterface(sourceType, superInterfaceRef, superInterface);
continue nextInterface;
}
}
@@ -824,22 +863,64 @@
noProblems = false;
continue nextInterface;
}
- ReferenceBinding invalid = findAmbiguousInterface(superInterface, sourceType);
- if (invalid != null) {
- ReferenceBinding generic = null;
- if (superInterface.isParameterizedType())
- generic = ((ParameterizedTypeBinding) superInterface).type;
- else if (invalid.isParameterizedType())
- generic = ((ParameterizedTypeBinding) invalid).type;
- problemReporter().superinterfacesCollide(generic, referenceContext, superInterface, invalid);
- sourceType.tagBits |= HierarchyHasProblems;
- noProblems = false;
- continue nextInterface;
- }
-
// only want to reach here when no errors are reported
interfaceBindings[count++] = superInterface;
}
+ // check for parameterized interface collisions (when different parameterizations occur)
+ if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
+ TypeBinding[] types = new TypeBinding[2];
+ Map invocations = new HashMap(2);
+ nextInterface: for (int i = 0; i < count; i++) {
+ ReferenceBinding superInterface = interfaceBindings[i];
+ // check against superclass
+ if (!sourceType.isInterface()) {
+ types[0] = sourceType.superclass;
+ types[1] = superInterface;
+ TypeBinding[] mecs = minimalErasedCandidates(types, invocations);
+ if (mecs != null) {
+ nextCandidate: for (int k = 0, max = mecs.length; k < max; k++) {
+ TypeBinding mec = mecs[k];
+ if (mec == null) continue nextCandidate;
+ Set invalidInvocations = (Set)invocations.get(mec);
+ int invalidSize = invalidInvocations.size();
+ if (invalidSize > 1) {
+ TypeBinding[] collisions;
+ invalidInvocations.toArray(collisions = new TypeBinding[invalidSize]);
+ problemReporter().superinterfacesCollide(collisions[0].erasure(), referenceContext, collisions[0], collisions[1]);
+ sourceType.tagBits |= HierarchyHasProblems;
+ noProblems = false;
+ continue nextInterface;
+ }
+ }
+ }
+ }
+ // check against other super-interfaces
+ types[0] = superInterface;
+ nextOtherInterface: for (int j = 0; j < i; j++) {
+ ReferenceBinding otherInterface = interfaceBindings[j];
+ if (otherInterface == null) continue nextOtherInterface;
+ types[1] = otherInterface;
+ invocations.clear();
+ TypeBinding[] mecs = minimalErasedCandidates(types, invocations);
+ if (mecs != null) {
+ nextCandidate: for (int k = 0, max = mecs.length; k < max; k++) {
+ TypeBinding mec = mecs[k];
+ if (mec == null) continue nextCandidate;
+ Set invalidInvocations = (Set)invocations.get(mec);
+ int invalidSize = invalidInvocations.size();
+ if (invalidSize > 1) {
+ TypeBinding[] collisions;
+ invalidInvocations.toArray(collisions = new TypeBinding[invalidSize]);
+ problemReporter().superinterfacesCollide(collisions[0].erasure(), referenceContext, collisions[0], collisions[1]);
+ sourceType.tagBits |= HierarchyHasProblems;
+ noProblems = false;
+ continue nextInterface;
+ }
+ }
+ }
+ }
+ }
+ }
// hold onto all correctly resolved superinterfaces
if (count > 0) {
if (count != length)
@@ -860,8 +941,6 @@
if (noProblems && sourceType.isHierarchyInconsistent())
problemReporter().hierarchyHasProblems(sourceType);
}
- // Perform deferred bound checks for parameterized type references (only done after hierarchy is connected)
- checkParameterizedTypeBounds();
connectMemberTypes();
try {
checkForInheritedMemberTypes(sourceType);
@@ -936,17 +1015,18 @@
return true;
}
- if (superType.isMemberType()) {
- ReferenceBinding current = superType.enclosingType();
- do {
- if (current.isHierarchyBeingConnected()) {
- problemReporter().hierarchyCircularity(sourceType, current, reference);
- sourceType.tagBits |= HierarchyHasProblems;
- current.tagBits |= HierarchyHasProblems;
- return true;
- }
- } while ((current = current.enclosingType()) != null);
- }
+// No longer believe this code is necessary, since we changed supertype lookup to use TypeReference resolution
+// if (superType.isMemberType()) {
+// ReferenceBinding current = superType.enclosingType();
+// do {
+// if (current.isHierarchyBeingConnected()) {
+// problemReporter().hierarchyCircularity(sourceType, current, reference);
+// sourceType.tagBits |= HierarchyHasProblems;
+// current.tagBits |= HierarchyHasProblems;
+// return true;
+// }
+// } while ((current = current.enclosingType()) != null);
+// }
if (superType.isBinaryBinding()) {
// force its superclass & superinterfaces to be found... 2 possibilities exist - the source type is included in the hierarchy of:
@@ -993,7 +1073,8 @@
}
if (superType.isHierarchyBeingConnected()) {
- if (((SourceTypeBinding) superType).scope.superTypeReference != null) { // if null then its connecting its type variables
+ org.eclipse.jdt.internal.compiler.ast.TypeReference ref = ((SourceTypeBinding) superType).scope.superTypeReference;
+ if (ref != null && ref.resolvedType != null && ((ReferenceBinding) ref.resolvedType).isHierarchyBeingConnected()) { // if null then its connecting its type variables
problemReporter().hierarchyCircularity(sourceType, superType, reference);
sourceType.tagBits |= HierarchyHasProblems;
superType.tagBits |= HierarchyHasProblems;
@@ -1008,40 +1089,6 @@
return false;
}
- private ReferenceBinding findAmbiguousInterface(ReferenceBinding newInterface, ReferenceBinding currentType) {
- TypeBinding newErasure = newInterface.erasure();
- if (newInterface == newErasure) return null;
-
- ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
- int lastPosition = -1;
- do {
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
- } while ((currentType = currentType.superclass()) != null);
-
- for (int i = 0; i <= lastPosition; i++) {
- ReferenceBinding[] interfaces = interfacesToVisit[i];
- for (int j = 0, length = interfaces.length; j < length; j++) {
- currentType = interfaces[j];
- if (currentType.erasure() == newErasure)
- if (currentType != newInterface)
- return currentType;
-
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
- }
- }
- return null;
- }
-
private ReferenceBinding findSupertype(TypeReference typeReference) {
try {
typeReference.aboutToResolve(this); // allows us to trap completion & selection nodes
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
index 56b966b..9ef88fc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
@@ -19,21 +19,21 @@
public class CompilationUnitScope extends Scope {
- public LookupEnvironment environment;
- public CompilationUnitDeclaration referenceContext;
- public char[][] currentPackageName;
- public PackageBinding fPackage;
- public ImportBinding[] imports;
- public HashtableOfObject resolvedSingeTypeImports;
-
- public SourceTypeBinding[] topLevelTypes;
+public LookupEnvironment environment;
+public CompilationUnitDeclaration referenceContext;
+public char[][] currentPackageName;
+public PackageBinding fPackage;
+public ImportBinding[] imports;
+public HashtableOfObject typeOrPackageCache; // used in Scope.getTypeOrPackage()
- private CompoundNameVector qualifiedReferences;
- private SimpleNameVector simpleNameReferences;
- private ObjectVector referencedTypes;
- private ObjectVector referencedSuperTypes;
-
- HashtableOfType constantPoolNameUsage;
+public SourceTypeBinding[] topLevelTypes;
+
+private CompoundNameVector qualifiedReferences;
+private SimpleNameVector simpleNameReferences;
+private ObjectVector referencedTypes;
+private ObjectVector referencedSuperTypes;
+
+HashtableOfType constantPoolNameUsage;
public CompilationUnitScope(CompilationUnitDeclaration unit, LookupEnvironment environment) {
super(COMPILATION_UNIT_SCOPE, null);
@@ -42,7 +42,7 @@
unit.scope = this;
this.currentPackageName = unit.currentPackage == null ? CharOperation.NO_CHAR_CHAR : unit.currentPackage.tokens;
- if (environment.options.produceReferenceInfo) {
+ if (compilerOptions().produceReferenceInfo) {
this.qualifiedReferences = new CompoundNameVector();
this.simpleNameReferences = new SimpleNameVector();
this.referencedTypes = new ObjectVector();
@@ -179,6 +179,10 @@
System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[index], 0, index);
imports = resolvedImports;
}
+void checkParameterizedTypeBounds() {
+ for (int i = 0, length = topLevelTypes.length; i < length; i++)
+ topLevelTypes[i].scope.checkParameterizedTypeBounds();
+}
/*
* INTERNAL USE-ONLY
* Innerclasses get their name computed as they are generated, since some may not
@@ -198,6 +202,7 @@
// ensure there is not already such a local type name defined by the user
int index = 0;
char[] candidateName;
+ boolean isCompliant15 = compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5;
while(true) {
if (localType.isMemberType()){
if (index == 0){
@@ -221,12 +226,22 @@
String.valueOf(index+1).toCharArray(),
'$');
} else {
+ // local type
+ if (isCompliant15) {
+ candidateName = CharOperation.concat(
+ CharOperation.concat(
+ outerMostEnclosingType.constantPoolName(),
+ String.valueOf(index+1).toCharArray(),
+ '$'),
+ localType.sourceName);
+ } else {
candidateName = CharOperation.concat(
outerMostEnclosingType.constantPoolName(),
'$',
String.valueOf(index+1).toCharArray(),
'$',
localType.sourceName);
+ }
}
if (constantPoolNameUsage.get(candidateName) != null) {
index ++;
@@ -243,8 +258,10 @@
topLevelTypes[i].scope.connectTypeHierarchy();
}
void faultInImports() {
- if (referenceContext.imports == null)
+ if (referenceContext.imports == null) {
+ this.typeOrPackageCache = new HashtableOfObject(1);
return;
+ }
// collect the top level type names if a single type import exists
int numberOfStatements = referenceContext.imports.length;
@@ -314,9 +331,15 @@
problemReporter().cannotImportPackage(importReference);
continue nextImport;
}
+ ReferenceBinding conflictingType = null;
+ if (importBinding instanceof MethodBinding) {
+ conflictingType = (ReferenceBinding) getType(compoundName, compoundName.length);
+ if (!conflictingType.isValidBinding())
+ conflictingType = null;
+ }
// collisions between an imported static field & a type should be checked according to spec... but currently not by javac
- if (importBinding instanceof ReferenceBinding) {
- ReferenceBinding referenceBinding = (ReferenceBinding) importBinding;
+ if (importBinding instanceof ReferenceBinding || conflictingType != null) {
+ ReferenceBinding referenceBinding = conflictingType == null ? (ReferenceBinding) importBinding : conflictingType;
if (importReference.isTypeUseDeprecated(referenceBinding, this))
problemReporter().deprecatedType(referenceBinding, importReference);
@@ -348,7 +371,9 @@
}
}
}
- resolvedImports[index++] = new ImportBinding(compoundName, false, importBinding, importReference);
+ resolvedImports[index++] = conflictingType == null
+ ? new ImportBinding(compoundName, false, importBinding, importReference)
+ : new ImportConflictBinding(compoundName, importBinding, conflictingType, importReference);
}
}
@@ -358,11 +383,11 @@
imports = resolvedImports;
int length = imports.length;
- resolvedSingeTypeImports = new HashtableOfObject(length);
+ this.typeOrPackageCache = new HashtableOfObject(length);
for (int i = 0; i < length; i++) {
ImportBinding binding = imports[i];
- if (!binding.onDemand && binding.resolvedImport instanceof ReferenceBinding)
- resolvedSingeTypeImports.put(binding.compoundName[binding.compoundName.length - 1], binding);
+ if (!binding.onDemand && binding.resolvedImport instanceof ReferenceBinding || binding instanceof ImportConflictBinding)
+ this.typeOrPackageCache.put(binding.compoundName[binding.compoundName.length - 1], binding);
}
}
public void faultInTypes() {
@@ -394,11 +419,11 @@
ReferenceBinding type;
if (binding == null) {
- if (environment.defaultPackage == null || environment.options.complianceLevel >= ClassFileConstants.JDK1_4)
- return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), NotFound);
+ if (environment.defaultPackage == null || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
+ return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), null, NotFound);
type = findType(compoundName[0], environment.defaultPackage, environment.defaultPackage);
if (type == null || !type.isValidBinding())
- return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), NotFound);
+ return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), null, NotFound);
i = 1; // reset to look for member types inside the default package type
} else {
type = (ReferenceBinding) binding;
@@ -412,7 +437,7 @@
// does not look for inherited member types on purpose, only immediate members
type = type.getMemberType(name);
if (type == null)
- return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), NotFound);
+ return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, i), null, NotFound);
}
if (!type.canBeSeenBy(fPackage))
return new ProblemReferenceBinding(compoundName, type, NotVisible);
@@ -422,11 +447,11 @@
if (compoundName.length == 1) {
// findType records the reference
// the name cannot be a package
- if (environment.defaultPackage == null || environment.options.complianceLevel >= ClassFileConstants.JDK1_4)
- return new ProblemReferenceBinding(compoundName, NotFound);
+ if (environment.defaultPackage == null || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
+ return new ProblemReferenceBinding(compoundName, null, NotFound);
ReferenceBinding typeBinding = findType(compoundName[0], environment.defaultPackage, fPackage);
if (typeBinding == null)
- return new ProblemReferenceBinding(compoundName, NotFound);
+ return new ProblemReferenceBinding(compoundName, null, NotFound);
return typeBinding;
}
@@ -442,7 +467,7 @@
if (binding instanceof PackageBinding) {
Binding temp = ((PackageBinding) binding).getTypeOrPackage(name);
if (temp != null && temp instanceof ReferenceBinding) // must resolve to a member type or field, not a top level type
- return new ProblemReferenceBinding(compoundName, InvalidTypeForStaticImport);
+ return new ProblemReferenceBinding(compoundName, (ReferenceBinding) temp, InvalidTypeForStaticImport);
return binding; // cannot be a package, error is caught in sender
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilerModifiers.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilerModifiers.java
index 395a1a5..6badbc2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilerModifiers.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilerModifiers.java
@@ -32,7 +32,7 @@
final int AccClearPrivateModifier = ASTNode.Bit27; // might be requested during private access emulation
final int AccBlankFinal = ASTNode.Bit27; // for blank final variables
final int AccIsDefaultConstructor = ASTNode.Bit27; // for default constructor
- final int AccPrivateUsed = ASTNode.Bit28; // used to diagnose unused private members
+ final int AccLocallyUsed = ASTNode.Bit28; // used to diagnose unused private/local members
final int AccVisibilityMASK = AccPublic | AccProtected | AccPrivate;
final int AccOverriding = ASTNode.Bit29; // record fact a method overrides another one
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
index 2dcd27a..d4d570a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
@@ -80,7 +80,7 @@
ReferenceBinding receiverErasure = (ReferenceBinding)receiverType.erasure();
ReferenceBinding declaringErasure = (ReferenceBinding) declaringClass.erasure();
do {
- if (currentType.findSuperTypeErasingTo(declaringErasure) != null) {
+ if (currentType.findSuperTypeWithSameErasure(declaringErasure) != null) {
if (invocationSite.isSuperAccess()){
return true;
}
@@ -92,7 +92,7 @@
if (depth > 0) invocationSite.setDepth(depth);
return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
}
- if (currentType == receiverErasure || receiverErasure.findSuperTypeErasingTo(currentType) != null){
+ if (currentType == receiverErasure || receiverErasure.findSuperTypeWithSameErasure(currentType) != null){
if (depth > 0) invocationSite.setDepth(depth);
return true;
}
@@ -151,43 +151,33 @@
}
/*
* declaringUniqueKey dot fieldName
- * p.X { X<T> x} --> Lp/X;.x^123
+ * p.X { X<T> x} --> Lp/X;.x)p/X<TT;>;
*/
-public char[] computeUniqueKey(boolean withAccessFlags) {
+public char[] computeUniqueKey(boolean isLeaf) {
// declaring key
char[] declaringKey =
this.declaringClass == null /*case of length field for an array*/
? CharOperation.NO_CHAR
- : this.declaringClass.computeUniqueKey(false/*without access flags*/);
+ : this.declaringClass.computeUniqueKey(false/*not a leaf*/);
int declaringLength = declaringKey.length;
// name
int nameLength = this.name.length;
- if (withAccessFlags) {
- // flags
- String flags = Integer.toString(getAccessFlags());
- int flagsLength = flags.length();
+ // return type
+ char[] returnTypeKey = this.type == null ? new char[] {'V'} : this.type.computeUniqueKey(false/*not a leaf*/);
+ int returnTypeLength = returnTypeKey.length;
- char[] uniqueKey = new char[declaringLength + 1 + nameLength + 1 + flagsLength];
- int index = 0;
- System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
- index += declaringLength;
- uniqueKey[index++] = '.';
- System.arraycopy(this.name, 0, uniqueKey, index, nameLength);
- index += nameLength;
- uniqueKey[index++] = '^';
- flags.getChars(0, flagsLength, uniqueKey, index);
- return uniqueKey;
- } else {
- char[] uniqueKey = new char[declaringLength + 1 + nameLength];
- int index = 0;
- System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
- index += declaringLength;
- uniqueKey[index++] = '.';
- System.arraycopy(this.name, 0, uniqueKey, index, nameLength);
- return uniqueKey;
- }
+ char[] uniqueKey = new char[declaringLength + 1 + nameLength + 1 + returnTypeLength];
+ int index = 0;
+ System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
+ index += declaringLength;
+ uniqueKey[index++] = '.';
+ System.arraycopy(this.name, 0, uniqueKey, index, nameLength);
+ index += nameLength;
+ uniqueKey[index++] = ')';
+ System.arraycopy(returnTypeKey, 0, uniqueKey, index, returnTypeLength);
+ return uniqueKey;
}
/**
* X<T> t --> LX<TT;>;
@@ -211,8 +201,19 @@
if ((originalField.tagBits & TagBits.AnnotationResolved) == 0 && originalField.declaringClass instanceof SourceTypeBinding) {
TypeDeclaration typeDecl = ((SourceTypeBinding)originalField.declaringClass).scope.referenceContext;
FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField);
- if (fieldDecl != null)
- ASTNode.resolveAnnotations(isStatic() ? typeDecl.staticInitializerScope : typeDecl.initializerScope, fieldDecl.annotations, originalField);
+ if (fieldDecl != null) {
+ MethodScope initializationScope = isStatic() ? typeDecl.staticInitializerScope : typeDecl.initializerScope;
+ FieldBinding previousField = initializationScope.initializedField;
+ int previousFieldID = initializationScope.lastVisibleFieldID;
+ try {
+ initializationScope.initializedField = originalField;
+ initializationScope.lastVisibleFieldID = originalField.id;
+ ASTNode.resolveAnnotations(initializationScope, fieldDecl.annotations, originalField);
+ } finally {
+ initializationScope.initializedField = previousField;
+ initializationScope.lastVisibleFieldID = previousFieldID;
+ }
+ }
}
return originalField.tagBits;
}
@@ -238,8 +239,8 @@
/* Answer true if the receiver has private visibility and is used locally
*/
-public final boolean isPrivateUsed() {
- return (modifiers & AccPrivateUsed) != 0;
+public final boolean isUsed() {
+ return (modifiers & AccLocallyUsed) != 0;
}
/* Answer true if the receiver has protected visibility
*/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportConflictBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportConflictBinding.java
new file mode 100644
index 0000000..5409b41
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportConflictBinding.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+
+public class ImportConflictBinding extends ImportBinding {
+public ReferenceBinding conflictingTypeBinding; // must ensure the import is resolved
+
+public ImportConflictBinding(char[][] compoundName, Binding methodBinding, ReferenceBinding conflictingTypeBinding, ImportReference reference) {
+ super(compoundName, false, methodBinding, reference);
+ this.conflictingTypeBinding = conflictingTypeBinding;
+}
+public char[] readableName() {
+ return CharOperation.concatWith(compoundName, '.');
+}
+public String toString() {
+ return "method import : " + new String(readableName()); //$NON-NLS-1$
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
index c96f153..9bc1b82 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
@@ -62,21 +62,17 @@
dependents[index] = new InnerEmulationDependency(dependentScope, wasEnclosingInstanceSupplied);
// System.out.println("Adding dependency: "+ new String(scope.enclosingType().readableName()) + " --> " + new String(this.readableName()));
}
-public char[] computeUniqueKey(boolean withAccessFlags) {
- ReferenceBinding enclosing = enclosingType();
- ReferenceBinding temp;
- while ((temp = enclosing.enclosingType()) != null)
- enclosing = temp;
- StringBuffer buffer = new StringBuffer();
- buffer.append(enclosing.computeUniqueKey(withAccessFlags));
- int semicolon = buffer.lastIndexOf(";"); //$NON-NLS-1$
- buffer.insert(semicolon, '$');
- semicolon = buffer.lastIndexOf(";"); //$NON-NLS-1$
- buffer.insert(semicolon, this.sourceStart);
- int length = buffer.length();
- char[] uniqueKey = new char[length];
- buffer.getChars(0, length, uniqueKey, 0);
- return uniqueKey;
+public char[] computeUniqueKey(boolean isLeaf) {
+ char[] outerKey = outermostEnclosingType().computeUniqueKey(isLeaf);
+ int semicolon = CharOperation.lastIndexOf(';', outerKey);
+
+ // insert $sourceStart
+ return CharOperation.concat(
+ CharOperation.concat(
+ CharOperation.subarray(outerKey, 0, semicolon),
+ String.valueOf(this.sourceStart).toCharArray(),
+ '$'),
+ CharOperation.subarray(outerKey, semicolon, outerKey.length));
}
public char[] constantPoolName() /* java/lang/Object */ {
@@ -100,6 +96,21 @@
return localArrayBindings[length] = new ArrayBinding(this, dimensionCount, scope.environment());
}
+/*
+ * Overriden for code assist. In this case, the constantPoolName() has not been computed yet.
+ * Slam the source name so that the signature is syntactically correct.
+ * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=99686)
+ */
+public char[] genericTypeSignature() {
+ if (this.genericReferenceTypeSignature == null && constantPoolName() == null) {
+ if (isAnonymousType())
+ setConstantPoolName(superclass().sourceName());
+ else
+ setConstantPoolName(sourceName());
+ }
+ return super.genericTypeSignature();
+}
+
public char[] readableName() /*java.lang.Object, p.X<T> */ {
char[] readableName;
if (isAnonymousType()) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java
index 80173f6..3757fdc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java
@@ -57,9 +57,9 @@
/*
* declaringUniqueKey # scopeIndex / varName
- * p.X { void foo() { int local; } } --> Lp/X;.foo()V#1/local^123
+ * p.X { void foo() { int local; } } --> Lp/X;.foo()V#1/local
*/
- public char[] computeUniqueKey(boolean withAccessFlags) {
+ public char[] computeUniqueKey(boolean isLeaf) {
StringBuffer buffer = new StringBuffer();
// declaring method or type
@@ -69,12 +69,12 @@
if (referenceContext instanceof AbstractMethodDeclaration) {
MethodBinding methodBinding = ((AbstractMethodDeclaration) referenceContext).binding;
if (methodBinding != null) {
- buffer.append(methodBinding.computeUniqueKey(false/*without access flags*/));
+ buffer.append(methodBinding.computeUniqueKey(false/*not a leaf*/));
}
} else if (referenceContext instanceof TypeDeclaration) {
TypeBinding typeBinding = ((TypeDeclaration) referenceContext).binding;
if (typeBinding != null) {
- buffer.append(typeBinding.computeUniqueKey(false/*without access flags*/));
+ buffer.append(typeBinding.computeUniqueKey(false/*not a leaf*/));
}
}
@@ -85,12 +85,6 @@
buffer.append('#');
buffer.append(this.name);
- // flags
- if (withAccessFlags) {
- buffer.append('^');
- buffer.append(this.modifiers & AccJustFlag);
- }
-
int length = buffer.length();
char[] uniqueKey = new char[length];
buffer.getChars(0, length, uniqueKey, 0);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 31bf1c8..ff4fbef 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -30,7 +30,7 @@
final static int CHECK_AND_SET_IMPORTS = 2;
final static int CONNECT_TYPE_HIERARCHY = 3;
static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(CharOperation.NO_CHAR, NotFound);
- static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR, NotFound);
+ static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR, null, NotFound);
/**
* Map from typeBinding -> accessRestriction rule
@@ -44,7 +44,7 @@
private int lastUnitIndex = -1;
public INameEnvironment nameEnvironment;
- public CompilerOptions options;
+ public CompilerOptions globalOptions;
public ProblemReporter problemReporter;
// shared byte[]'s used by ClassFile to avoid allocating MBs during a build
@@ -68,9 +68,9 @@
private CompilationUnitDeclaration[] units = new CompilationUnitDeclaration[4];
private MethodVerifier verifier;
-public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions options, ProblemReporter problemReporter, INameEnvironment nameEnvironment) {
+public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions globalOptions, ProblemReporter problemReporter, INameEnvironment nameEnvironment) {
this.typeRequestor = typeRequestor;
- this.options = options;
+ this.globalOptions = globalOptions;
this.problemReporter = problemReporter;
this.defaultPackage = new PackageBinding(this); // assume the default package always exists
this.defaultImports = null;
@@ -197,7 +197,9 @@
stepCompleted = CONNECT_TYPE_HIERARCHY;
for (int i = this.lastCompletedUnitIndex + 1; i <= this.lastUnitIndex; i++) {
- (this.unitBeingCompleted = this.units[i]).scope.buildFieldsAndMethods();
+ CompilationUnitScope unitScope = (this.unitBeingCompleted = this.units[i]).scope;
+ unitScope.checkParameterizedTypeBounds();
+ unitScope.buildFieldsAndMethods();
this.units[i] = null; // release unnecessary reference to the parsed unit
}
stepCompleted = BUILD_FIELDS_AND_METHODS;
@@ -247,6 +249,7 @@
(this.unitBeingCompleted = parsedUnit).scope.checkAndSetImports();
parsedUnit.scope.connectTypeHierarchy();
+ parsedUnit.scope.checkParameterizedTypeBounds();
if (buildFieldsAndMethods)
parsedUnit.scope.buildFieldsAndMethods();
this.unitBeingCompleted = null;
@@ -274,35 +277,35 @@
case TypeIds.T_int :
boxedType = getType(JAVA_LANG_INTEGER);
if (boxedType != null) return boxedType;
- return new ProblemReferenceBinding( JAVA_LANG_INTEGER, NotFound);
+ return new ProblemReferenceBinding( JAVA_LANG_INTEGER, null, NotFound);
case TypeIds.T_byte :
boxedType = getType(JAVA_LANG_BYTE);
if (boxedType != null) return boxedType;
- return new ProblemReferenceBinding( JAVA_LANG_BYTE, NotFound);
+ return new ProblemReferenceBinding( JAVA_LANG_BYTE, null, NotFound);
case TypeIds.T_short :
boxedType = getType(JAVA_LANG_SHORT);
if (boxedType != null) return boxedType;
- return new ProblemReferenceBinding( JAVA_LANG_SHORT, NotFound);
+ return new ProblemReferenceBinding( JAVA_LANG_SHORT, null, NotFound);
case TypeIds.T_char :
boxedType = getType(JAVA_LANG_CHARACTER);
if (boxedType != null) return boxedType;
- return new ProblemReferenceBinding( JAVA_LANG_CHARACTER, NotFound);
+ return new ProblemReferenceBinding( JAVA_LANG_CHARACTER, null, NotFound);
case TypeIds.T_long :
boxedType = getType(JAVA_LANG_LONG);
if (boxedType != null) return boxedType;
- return new ProblemReferenceBinding( JAVA_LANG_LONG, NotFound);
+ return new ProblemReferenceBinding( JAVA_LANG_LONG, null, NotFound);
case TypeIds.T_float :
boxedType = getType(JAVA_LANG_FLOAT);
if (boxedType != null) return boxedType;
- return new ProblemReferenceBinding( JAVA_LANG_FLOAT, NotFound);
+ return new ProblemReferenceBinding( JAVA_LANG_FLOAT, null, NotFound);
case TypeIds.T_double :
boxedType = getType(JAVA_LANG_DOUBLE);
if (boxedType != null) return boxedType;
- return new ProblemReferenceBinding( JAVA_LANG_DOUBLE, NotFound);
+ return new ProblemReferenceBinding( JAVA_LANG_DOUBLE, null, NotFound);
case TypeIds.T_boolean :
boxedType = getType(JAVA_LANG_BOOLEAN);
if (boxedType != null) return boxedType;
- return new ProblemReferenceBinding( JAVA_LANG_BOOLEAN, NotFound);
+ return new ProblemReferenceBinding( JAVA_LANG_BOOLEAN, null, NotFound);
}
// allow indirect unboxing conversion for wildcards and type parameters
switch (type.kind()) {
@@ -349,11 +352,83 @@
return packageBinding;
}
+public TypeBinding convertToRawType(TypeBinding type) {
+
+ int dimension;
+ TypeBinding originalType;
+ switch(type.kind()) {
+ case Binding.BASE_TYPE :
+ case Binding.TYPE_PARAMETER:
+ case Binding.WILDCARD_TYPE:
+ case Binding.RAW_TYPE:
+ return type;
+ case Binding.ARRAY_TYPE:
+ dimension = type.dimensions();
+ originalType = type.leafComponentType();
+ break;
+ default:
+ dimension = 0;
+ originalType = type;
+ }
+ boolean needToConvert;
+ switch (originalType.kind()) {
+ case Binding.BASE_TYPE :
+ return type;
+ case Binding.GENERIC_TYPE :
+ needToConvert = true;
+ break;
+ case Binding.PARAMETERIZED_TYPE :
+ ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType;
+ needToConvert = paramType.type.isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
+ break;
+ default :
+ needToConvert = false;
+ break;
+ }
+ ReferenceBinding originalEnclosing = originalType.enclosingType();
+ TypeBinding convertedType;
+ if (originalEnclosing == null) {
+ convertedType = needToConvert ? createRawType((ReferenceBinding)originalType.erasure(), null) : originalType;
+ } else {
+ ReferenceBinding convertedEnclosing;
+ switch (originalEnclosing.kind()) {
+ case Binding.GENERIC_TYPE :
+ case Binding.PARAMETERIZED_TYPE :
+ if (needToConvert || ((ReferenceBinding)originalType).isStatic()) {
+ convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing);
+ } else {
+ convertedEnclosing = originalEnclosing;
+ }
+ break;
+ case Binding.RAW_TYPE :
+ needToConvert |= !((ReferenceBinding)originalType).isStatic();
+ default :
+ convertedEnclosing = originalEnclosing;
+ break;
+ }
+ ReferenceBinding originalGeneric = (ReferenceBinding) originalType.erasure();
+ if (needToConvert) {
+ convertedType = createRawType(originalGeneric, convertedEnclosing);
+ } else if (originalEnclosing != convertedEnclosing) {
+ if (originalGeneric.isStatic())
+ convertedType = createParameterizedType(originalGeneric, null, convertedEnclosing);
+ else
+ convertedType = createRawType(originalGeneric, convertedEnclosing);
+ } else {
+ convertedType = originalType;
+ }
+ }
+ if (originalType != convertedType) {
+ return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType;
+ }
+ return type;
+}
+
/* Used to guarantee array type identity.
*/
-public ArrayBinding createArrayType(TypeBinding type, int dimensionCount) {
- if (type instanceof LocalTypeBinding) // cache local type arrays with the local type itself
- return ((LocalTypeBinding) type).createArrayType(dimensionCount);
+public ArrayBinding createArrayType(TypeBinding leafComponentType, int dimensionCount) {
+ if (leafComponentType instanceof LocalTypeBinding) // cache local type arrays with the local type itself
+ return ((LocalTypeBinding) leafComponentType).createArrayType(dimensionCount);
// find the array binding cache for this dimension
int dimIndex = dimensionCount - 1;
@@ -376,8 +451,8 @@
while (++index < length) {
ArrayBinding currentBinding = arrayBindings[index];
if (currentBinding == null) // no matching array, but space left
- return arrayBindings[index] = new ArrayBinding(type, dimensionCount, this);
- if (currentBinding.leafComponentType == type)
+ return arrayBindings[index] = new ArrayBinding(leafComponentType, dimensionCount, this);
+ if (currentBinding.leafComponentType == leafComponentType)
return currentBinding;
}
@@ -387,7 +462,7 @@
(arrayBindings = new ArrayBinding[length * 2]), 0,
length);
uniqueArrayBindings[dimIndex] = arrayBindings;
- return arrayBindings[length] = new ArrayBinding(type, dimensionCount, this);
+ return arrayBindings[length] = new ArrayBinding(leafComponentType, dimensionCount, this);
}
public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
return createBinaryTypeFrom(binaryType, packageBinding, true, accessRestriction);
@@ -398,11 +473,15 @@
// resolve any array bindings which reference the unresolvedType
ReferenceBinding cachedType = packageBinding.getType0(binaryBinding.compoundName[binaryBinding.compoundName.length - 1]);
if (cachedType != null) { // update reference to unresolved binding after having read classfile (knows whether generic for raw conversion)
- // TODO (kent) suspect the check below is no longer required, since we should not be requesting a binary which is already in the cache
- if (cachedType.isBinaryBinding()) // sanity check before the cast... at this point the cache should ONLY contain unresolved types
- return (BinaryTypeBinding) cachedType;
-
- ((UnresolvedReferenceBinding) cachedType).setResolvedType(binaryBinding, this);
+ if (cachedType instanceof UnresolvedReferenceBinding) {
+ ((UnresolvedReferenceBinding) cachedType).setResolvedType(binaryBinding, this);
+ } else {
+ if (cachedType.isBinaryBinding()) // sanity check... at this point the cache should ONLY contain unresolved types
+ return (BinaryTypeBinding) cachedType;
+ // it is possible with a large number of source files (exceeding AbstractImageBuilder.MAX_AT_ONCE) that a member type can be in the cache as an UnresolvedType,
+ // but because its enclosingType is resolved while its created (call to BinaryTypeBinding constructor), its replaced with a source type
+ return null;
+ }
}
packageBinding.addType(binaryBinding);
@@ -668,7 +747,7 @@
// compoundName refers to a nested type incorrectly (for example, package1.A$B)
if (referenceBinding.isNestedType())
- return new ProblemReferenceBinding(compoundName, InternalNameProvided);
+ return new ProblemReferenceBinding(compoundName, referenceBinding, InternalNameProvided);
return referenceBinding;
}
private TypeBinding[] getTypeArgumentsFromSignature(SignatureWrapper wrapper, TypeVariableBinding[] staticVariables, ReferenceBinding enclosingType, ReferenceBinding genericType) {
@@ -704,9 +783,9 @@
} else if (binding == TheNotFoundType) {
problemReporter.isClassPathCorrect(compoundName, null);
return null; // will not get here since the above error aborts the compilation
- } else if (!isParameterized && binding.isGenericType()) {
+ } else if (!isParameterized) {
// check raw type, only for resolved types
- binding = createRawType(binding, binding.enclosingType());
+ binding = (ReferenceBinding)convertToRawType(binding);
}
return binding;
}
@@ -809,7 +888,11 @@
// type must be a ReferenceBinding at this point, cannot be a BaseTypeBinding or ArrayTypeBinding
ReferenceBinding actualType = (ReferenceBinding) type;
TypeBinding[] typeArguments = getTypeArgumentsFromSignature(wrapper, staticVariables, enclosingType, actualType);
- ParameterizedTypeBinding parameterizedType = createParameterizedType(actualType, typeArguments, null);
+ ReferenceBinding actualEnclosing = actualType.enclosingType();
+ if (actualEnclosing != null) { // convert needed if read some static member type
+ actualEnclosing = (ReferenceBinding) convertToRawType(actualEnclosing);
+ }
+ ParameterizedTypeBinding parameterizedType = createParameterizedType(actualType, typeArguments, actualEnclosing);
while (wrapper.signature[wrapper.start] == '.') {
wrapper.start++; // skip '.'
@@ -856,13 +939,7 @@
return getTypeFromTypeSignature(wrapper, staticVariables, enclosingType);
}
}
-public boolean isBoxingCompatibleWith(TypeBinding left, TypeBinding right) {
- if (options.sourceLevel < ClassFileConstants.JDK1_5 || left.isBaseType() == right.isBaseType())
- return false;
- TypeBinding convertedType = computeBoxingType(left);
- return convertedType == right || convertedType.isCompatibleWith(right);
-}
/* Ask the oracle if a package exists named name in the package named compoundName.
*/
boolean isPackage(char[][] compoundName, char[] name) {
@@ -874,7 +951,7 @@
public MethodVerifier methodVerifier() {
if (verifier == null)
- verifier = this.options.complianceLevel < ClassFileConstants.JDK1_5
+ verifier = this.globalOptions.complianceLevel < ClassFileConstants.JDK1_5
? new MethodVerifier(this)
: new MethodVerifier15(this); // check for covariance even if sourceLevel is < 1.5
return verifier;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
index 766a764..728f220 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
@@ -219,7 +219,7 @@
ReferenceBinding declaringErasure = (ReferenceBinding) declaringClass.erasure();
int depth = 0;
do {
- if (currentType.findSuperTypeErasingTo(declaringErasure) != null) {
+ if (currentType.findSuperTypeWithSameErasure(declaringErasure) != null) {
if (invocationSite.isSuperAccess()){
return true;
}
@@ -231,7 +231,7 @@
if (depth > 0) invocationSite.setDepth(depth);
return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
}
- if (currentType == receiverErasure || ((ReferenceBinding)receiverErasure).findSuperTypeErasingTo(currentType) != null){
+ if (currentType == receiverErasure || ((ReferenceBinding)receiverErasure).findSuperTypeWithSameErasure(currentType) != null){
if (depth > 0) invocationSite.setDepth(depth);
return true;
}
@@ -288,16 +288,30 @@
} while ((type = type.superclass()) != null);
return false;
}
+MethodBinding computeSubstitutedMethod(MethodBinding method, LookupEnvironment env) {
+ TypeVariableBinding[] vars = this.typeVariables;
+ TypeVariableBinding[] vars2 = method.typeVariables;
+ if (vars.length != vars2.length)
+ return null;
+ for (int v = vars.length; --v >= 0;)
+ if (!vars[v].isInterchangeableWith(env, vars2[v]))
+ return null;
+
+ // must substitute to detect cases like:
+ // <T1 extends X<T1>> void dup() {}
+ // <T2 extends X<T2>> Object dup() {return null;}
+ return new ParameterizedGenericMethodBinding(method, vars, env);
+}
/*
* declaringUniqueKey dot selector genericSignature
- * p.X { <T> void bar(X<T> t) } --> Lp/X;.bar<T:Ljava/lang/Object;>(LX<TT;>;)V^123
+ * p.X { <T> void bar(X<T> t) } --> Lp/X;.bar<T:Ljava/lang/Object;>(LX<TT;>;)V
*/
-public char[] computeUniqueKey(boolean withAccessFlags) {
- return computeUniqueKey(this, withAccessFlags);
+public char[] computeUniqueKey(boolean isLeaf) {
+ return computeUniqueKey(this, isLeaf);
}
-protected char[] computeUniqueKey(MethodBinding methodBinding, boolean withAccessFlags) {
+protected char[] computeUniqueKey(MethodBinding methodBinding, boolean isLeaf) {
// declaring class
- char[] declaringKey = this.declaringClass.computeUniqueKey(false/*without access flags*/);
+ char[] declaringKey = this.declaringClass.computeUniqueKey(false/*not a leaf*/);
int declaringLength = declaringKey.length;
// selector
@@ -308,36 +322,16 @@
if (sig == null) sig = methodBinding.signature();
int signatureLength = sig.length;
- if (withAccessFlags) {
- // flags
- String flags = Integer.toString(methodBinding.getAccessFlags());
- int flagsLength = flags.length();
-
- char[] uniqueKey = new char[declaringLength + 1 + selectorLength + signatureLength + 1 + flagsLength];
- int index = 0;
- System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
- index = declaringLength;
- uniqueKey[index++] = '.';
- System.arraycopy(this.selector, 0, uniqueKey, index, selectorLength);
- index += selectorLength;
- System.arraycopy(sig, 0, uniqueKey, index, signatureLength);
- index += signatureLength;
- uniqueKey[index++] = '^';
- flags.getChars(0, flagsLength, uniqueKey, index);
- // index += modifiersLength
- return uniqueKey;
- } else {
- char[] uniqueKey = new char[declaringLength + 1 + selectorLength + signatureLength];
- int index = 0;
- System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
- index = declaringLength;
- uniqueKey[index++] = '.';
- System.arraycopy(this.selector, 0, uniqueKey, index, selectorLength);
- index += selectorLength;
- System.arraycopy(sig, 0, uniqueKey, index, signatureLength);
- //index += signatureLength;
- return uniqueKey;
- }
+ char[] uniqueKey = new char[declaringLength + 1 + selectorLength + signatureLength];
+ int index = 0;
+ System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
+ index = declaringLength;
+ uniqueKey[index++] = '.';
+ System.arraycopy(this.selector, 0, uniqueKey, index, selectorLength);
+ index += selectorLength;
+ System.arraycopy(sig, 0, uniqueKey, index, signatureLength);
+ //index += signatureLength;
+ return uniqueKey;
}
/*
* Answer the declaring class to use in the constant pool
@@ -524,8 +518,8 @@
/* Answer true if the receiver has private visibility and is used locally
*/
-public final boolean isPrivateUsed() {
- return (modifiers & AccPrivateUsed) != 0;
+public final boolean isUsed() {
+ return (modifiers & AccLocallyUsed) != 0;
}
/* Answer true if the receiver has protected visibility
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
index 39d9264..4a97210 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
@@ -20,7 +20,6 @@
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo;
-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
@@ -212,10 +211,9 @@
if (referenceContext instanceof AbstractMethodDeclaration) {
AbstractMethodDeclaration methodDecl = (AbstractMethodDeclaration)referenceContext;
MethodBinding method = methodDecl.binding;
- CompilerOptions options = compilationUnitScope().environment.options;
if (!(method.isAbstract()
- || (method.isImplementing() && !options.reportUnusedParameterWhenImplementingAbstract)
- || (method.isOverriding() && !method.isImplementing() && !options.reportUnusedParameterWhenOverridingConcrete)
+ || (method.isImplementing() && !compilerOptions().reportUnusedParameterWhenImplementingAbstract)
+ || (method.isOverriding() && !method.isImplementing() && !compilerOptions().reportUnusedParameterWhenOverridingConcrete)
|| method.isMain())) {
isReportingUnusedArgument = true;
}
@@ -300,7 +298,7 @@
Argument[] argTypes = method.arguments;
int argLength = argTypes == null ? 0 : argTypes.length;
- if (argLength > 0 && environment().options.sourceLevel >= ClassFileConstants.JDK1_5) {
+ if (argLength > 0 && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
if (argTypes[--argLength].isVarArgs())
method.binding.modifiers |= AccVarargs;
while (--argLength >= 0) {
@@ -311,7 +309,7 @@
TypeParameter[] typeParameters = method.typeParameters();
// do not construct type variables if source < 1.5
- if (typeParameters == null || environment().options.sourceLevel < ClassFileConstants.JDK1_5) {
+ if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) {
method.binding.typeVariables = NoTypeVariables;
} else {
method.binding.typeVariables = createTypeVariables(typeParameters, method.binding);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
index a51f5bc..0046db1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
@@ -12,6 +12,7 @@
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
@@ -100,6 +101,7 @@
}
void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] methods, int length, MethodBinding[] otherInheritedMethods) {
boolean isAnnotationMember = this.type.isAnnotationType();
+ CompilerOptions options = type.scope.compilerOptions();
nextMethod : for (int i = length; --i >= 0;) {
MethodBinding inheritedMethod = methods[i];
if (isAnnotationMember) { // annotation cannot override any method
@@ -135,8 +137,8 @@
problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod);
if (!isAsVisible(currentMethod, inheritedMethod))
problemReporter(currentMethod).visibilityConflict(currentMethod, inheritedMethod);
- if (environment.options.reportDeprecationWhenOverridingDeprecatedMethod && inheritedMethod.isViewedAsDeprecated()) {
- if (!currentMethod.isViewedAsDeprecated() || environment.options.reportDeprecationInsideDeprecatedCode) {
+ if (options.reportDeprecationWhenOverridingDeprecatedMethod && inheritedMethod.isViewedAsDeprecated()) {
+ if (!currentMethod.isViewedAsDeprecated() || options.reportDeprecationInsideDeprecatedCode) {
// check against the other inherited methods to see if they hide this inheritedMethod
ReferenceBinding declaringClass = inheritedMethod.declaringClass;
if (declaringClass.isInterface())
@@ -176,7 +178,7 @@
int j = inheritedExceptions.length;
while (--j > -1 && !isSameClassOrSubclassOf(newException, inheritedExceptions[j])){/*empty*/}
if (j == -1)
- if (!(newException.isCompatibleWith(runtimeException()) || newException.isCompatibleWith(errorException())))
+ if (!newException.isUncheckedException(false))
problemReporter(newMethod).incompatibleExceptionInThrowsClause(this.type, newMethod, inheritedMethod, newException);
}
}
@@ -275,9 +277,8 @@
while (index >= 0) matchingInherited[index--] = null; // clear the previous contents of the matching methods
MethodBinding currentMethod = current[i];
for (int j = 0, length2 = inherited.length; j < length2; j++) {
- MethodBinding inheritedMethod = inherited[j];
+ MethodBinding inheritedMethod = computeSubstituteMethod(inherited[j], currentMethod);
if (inheritedMethod != null) {
- inheritedMethod = computeSubstituteMethod(inheritedMethod, currentMethod);
if (areMethodsEqual(currentMethod, inheritedMethod)) {
matchingInherited[++index] = inheritedMethod;
inherited[j] = null; // do not want to find it again
@@ -301,11 +302,13 @@
if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
continue;
otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
- if (areMethodsEqual(inheritedMethod, otherInheritedMethod)) {
- matchingInherited[++index] = otherInheritedMethod;
- inherited[j] = null; // do not want to find it again
- } else {
- checkForInheritedNameClash(inheritedMethod, otherInheritedMethod);
+ if (otherInheritedMethod != null) {
+ if (areMethodsEqual(inheritedMethod, otherInheritedMethod)) {
+ matchingInherited[++index] = otherInheritedMethod;
+ inherited[j] = null; // do not want to find it again
+ } else {
+ checkForInheritedNameClash(inheritedMethod, otherInheritedMethod);
+ }
}
}
}
@@ -507,20 +510,12 @@
}
}
MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
+ if (inheritedMethod == null) return null;
+ if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
return inheritedMethod;
}
public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
- return areReturnTypesEqual(method, inheritedMethod) && areMethodsEqual(method, inheritedMethod);
-}
-public boolean doReturnTypesCollide(MethodBinding method, MethodBinding inheritedMethod) {
- return method.returnType != inheritedMethod.returnType
- && org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector)
- && method.areParametersEqual(inheritedMethod);
-}
-ReferenceBinding errorException() {
- if (errorException == null)
- this.errorException = this.type.scope.getJavaLangError();
- return errorException;
+ return areMethodsEqual(method, inheritedMethod) && areReturnTypesEqual(method, inheritedMethod);
}
boolean isAsVisible(MethodBinding newMethod, MethodBinding inheritedMethod) {
if (inheritedMethod.modifiers == newMethod.modifiers) return true;
@@ -585,11 +580,6 @@
exceptions[i] = BinaryTypeBinding.resolveType(exceptions[i], this.environment, true);
return exceptions;
}
-ReferenceBinding runtimeException() {
- if (runtimeException == null)
- this.runtimeException = this.type.scope.getJavaLangRuntimeException();
- return runtimeException;
-}
void verify(SourceTypeBinding someType) {
this.type = someType;
computeMethods();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
index bab6c81..b4ab0e6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
@@ -10,11 +10,6 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
-import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.env.IConstants;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
class MethodVerifier15 extends MethodVerifier {
@@ -36,8 +31,9 @@
for (int i = 0; i < length; i++) {
if (!areTypesEqual(oneArgs[i], twoArgs[i])) {
// methods with raw parameters are considered equal to inherited methods with parameterized parameters for backwards compatibility
- if (oneArgs[i].isRawType() && !one.declaringClass.isInterface() && oneArgs[i].isEquivalentTo(twoArgs[i]))
- continue;
+ if (!one.declaringClass.isInterface() && oneArgs[i].leafComponentType().isRawType())
+ if (oneArgs[i].dimensions() == twoArgs[i].dimensions() && oneArgs[i].leafComponentType().isEquivalentTo(twoArgs[i].leafComponentType()))
+ continue;
return false;
}
}
@@ -298,7 +294,7 @@
if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
continue;
otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
- if (areMethodsEqual(inheritedMethod, otherInheritedMethod)) {
+ if (otherInheritedMethod != null && areMethodsEqual(inheritedMethod, otherInheritedMethod)) {
matchingInherited[++index] = otherInheritedMethod;
inherited[j] = null; // do not want to find it again
}
@@ -311,6 +307,7 @@
}
MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
if (inheritedMethod == null) return null;
+ if (currentMethod.parameters.length != inheritedMethod.parameters.length) return null; // no match
// due to hierarchy & compatibility checks, we need to ensure these 2 methods are resolved
if (currentMethod.declaringClass instanceof BinaryTypeBinding)
@@ -318,11 +315,10 @@
if (inheritedMethod.declaringClass instanceof BinaryTypeBinding)
((BinaryTypeBinding) inheritedMethod.declaringClass).resolveTypesFor(inheritedMethod);
- TypeVariableBinding[] inheritedTypeVariables = inheritedMethod.typeVariables();
+ TypeVariableBinding[] inheritedTypeVariables = inheritedMethod.typeVariables;
if (inheritedTypeVariables == NoTypeVariables) return inheritedMethod;
- TypeVariableBinding[] typeVariables = currentMethod == null ? NoTypeVariables : currentMethod.typeVariables;
-
int inheritedLength = inheritedTypeVariables.length;
+ TypeVariableBinding[] typeVariables = currentMethod.typeVariables;
int length = typeVariables.length;
TypeBinding[] arguments = new TypeBinding[inheritedLength];
if (inheritedLength <= length) {
@@ -330,7 +326,7 @@
} else {
System.arraycopy(typeVariables, 0, arguments, 0, length);
for (int i = length; i < inheritedLength; i++)
- arguments[i] = inheritedTypeVariables[i].erasure();
+ arguments[i] = inheritedTypeVariables[i].upperBound();
}
ParameterizedGenericMethodBinding substitute =
new ParameterizedGenericMethodBinding(inheritedMethod, arguments, this.environment);
@@ -357,7 +353,8 @@
return false;
}
public boolean doesMethodOverride(MethodBinding one, MethodBinding two) {
- return super.doesMethodOverride(one, computeSubstituteMethod(two, one));
+ MethodBinding sub = computeSubstituteMethod(two, one);
+ return sub != null && super.doesMethodOverride(one, sub);
}
boolean doParametersClash(MethodBinding one, MethodBinding substituteTwo) {
// must check each parameter pair to see if parameterized types are compatible
@@ -381,45 +378,18 @@
}
return false;
}
-public boolean doReturnTypesCollide(MethodBinding method, MethodBinding inheritedMethod) {
- MethodBinding sub = computeSubstituteMethod(inheritedMethod, method);
- return org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, sub.selector)
- && method.areParameterErasuresEqual(sub)
- && !areReturnTypesEqual(method, sub);
-}
boolean doTypeVariablesClash(MethodBinding one, MethodBinding substituteTwo) {
return one.typeVariables != NoTypeVariables && !one.areTypeVariableErasuresEqual(substituteTwo.original());
}
boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) {
+ if (inheritedMethod.original() != inheritedMethod && existingMethod.declaringClass.isInterface())
+ return false; // must hold onto ParameterizedMethod to see if a bridge method is necessary
+
inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod);
- return inheritedMethod.returnType == existingMethod.returnType
+ return inheritedMethod != null
+ && inheritedMethod.returnType == existingMethod.returnType
&& super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType);
}
-boolean mustImplementAbstractMethod(ReferenceBinding declaringClass) {
- if (!this.type.isEnum())
- return super.mustImplementAbstractMethod(declaringClass);
- if (this.type.isAnonymousType())
- return true; // body of enum constant must implement any inherited abstract methods
- if (this.type.isAbstract())
- return false; // is an enum that has since been tagged as abstract by the code below
-
- // enum type needs to implement abstract methods if one of its constants does not supply a body
- TypeDeclaration typeDeclaration = this.type.scope.referenceContext;
- FieldDeclaration[] fields = typeDeclaration.fields;
- int length = typeDeclaration.fields == null ? 0 : typeDeclaration.fields.length;
- if (length == 0) return true; // has no constants so must implement the method itself
- for (int i = 0; i < length; i++) {
- FieldDeclaration fieldDecl = fields[i];
- if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT)
- if (!(fieldDecl.initialization instanceof QualifiedAllocationExpression))
- return true;
- }
-
- // tag this enum as abstract since an abstract method must be implemented AND all enum constants define an anonymous body
- // as a result, each of its anonymous constants will see it as abstract and must implement each inherited abstract method
- this.type.modifiers |= IConstants.AccAbstract;
- return false;
-}
void verify(SourceTypeBinding someType) {
if (someType.isAnnotationType())
someType.detectAnnotationCycle();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
index 1e220cd..a6cb34c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
@@ -209,7 +209,7 @@
if (!onlyExactMatch){
for (int i = enclosingInstances.length; --i >= 0;)
if (enclosingInstances[i].actualOuterLocalVariable == null)
- if (((ReferenceBinding)enclosingInstances[i].type).findSuperTypeErasingTo(targetEnclosingType) != null)
+ if (((ReferenceBinding)enclosingInstances[i].type).findSuperTypeWithSameErasure(targetEnclosingType) != null)
return enclosingInstances[i];
}
return null;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
index d62d0cc..f4bf02e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
@@ -68,7 +68,7 @@
* slash separated name
* org.eclipse.jdt.core --> org/eclipse/jdt/core
*/
-public char[] computeUniqueKey(boolean withAccessFlags) {
+public char[] computeUniqueKey(boolean isLeaf) {
return CharOperation.concatWith(compoundName, '/');
}
private PackageBinding findPackage(char[] name) {
@@ -135,7 +135,7 @@
typeBinding = BinaryTypeBinding.resolveType(typeBinding, environment, false); // no raw conversion for now
if (typeBinding.isNestedType())
- return new ProblemReferenceBinding(name, InternalNameProvided);
+ return new ProblemReferenceBinding(name, typeBinding, InternalNameProvided);
return typeBinding;
}
/* Answer the type named name if it exists in the cache.
@@ -166,7 +166,7 @@
if (typeBinding != null && typeBinding != LookupEnvironment.TheNotFoundType) {
typeBinding = BinaryTypeBinding.resolveType(typeBinding, environment, false); // no raw conversion for now
if (typeBinding.isNestedType())
- return new ProblemReferenceBinding(name, InternalNameProvided);
+ return new ProblemReferenceBinding(name, typeBinding, InternalNameProvided);
return typeBinding;
}
@@ -177,7 +177,7 @@
if (typeBinding == null) { // have not looked for it before
if ((typeBinding = environment.askForType(this, name)) != null) {
if (typeBinding.isNestedType())
- return new ProblemReferenceBinding(name, InternalNameProvided);
+ return new ProblemReferenceBinding(name, typeBinding, InternalNameProvided);
return typeBinding;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java
index ab78214..7f8ef3d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java
@@ -25,7 +25,11 @@
public ParameterizedFieldBinding(ParameterizedTypeBinding parameterizedDeclaringClass, FieldBinding originalField) {
super (
originalField.name,
- originalField.isStatic() ? originalField.type : Scope.substitute(parameterizedDeclaringClass, originalField.type),
+ (originalField.modifiers & AccEnum) != 0
+ ? parameterizedDeclaringClass // enum constant get paramType as its type
+ : (originalField.modifiers & AccStatic) != 0
+ ? originalField.type // no subst for static field
+ : Scope.substitute(parameterizedDeclaringClass, originalField.type),
originalField.modifiers,
parameterizedDeclaringClass,
null);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
index 659cde6..2b04872 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
@@ -68,23 +68,13 @@
// 15.12.2.8 - inferring unresolved type arguments
if (hasUnresolvedTypeArgument(substitutes)) {
TypeBinding expectedType = null;
- // if message invocation has expected type
- if (invocationSite instanceof MessageSend) {
- MessageSend message = (MessageSend) invocationSite;
- expectedType = message.expectedType;
- }
- TypeBinding upperBound = null;
- if (methodSubstitute.returnType.isTypeVariable()) {
- // should be: if no expected type, then assume Object
- // actually it rather seems to handle the returned variable case by expecting its erasure instead
- upperBound = methodSubstitute.returnType.erasure();
- } else {
- if (methodSubstitute.returnType.id != TypeIds.T_void)
- upperBound = scope.getJavaLangObject();
- }
- // Object o = foo(); // where <T extends Serializable> T foo();
- if (expectedType == null || upperBound.isCompatibleWith(expectedType)) {
- expectedType = upperBound;
+ if (methodSubstitute.returnType != VoidBinding) {
+ // if message invocation has expected type
+ if (invocationSite instanceof MessageSend) {
+ MessageSend message = (MessageSend) invocationSite;
+ expectedType = message.expectedType;
+ }
+ if (expectedType == null) expectedType = scope.getJavaLangObject(); // assume Object by default
}
methodSubstitute = methodSubstitute.inferFromExpectedType(scope, expectedType, collectedSubstitutes, substitutes);
if (methodSubstitute == null)
@@ -100,7 +90,12 @@
switch (typeVariable.boundCheck(methodSubstitute, substitute)) {
case TypeConstants.MISMATCH :
// incompatible due to bound check
- return new ProblemMethodBinding(methodSubstitute, originalMethod.selector, new TypeBinding[]{substitute, typeVariables[i] }, ParameterBoundMismatch);
+ int argLength = arguments.length;
+ TypeBinding[] augmentedArguments = new TypeBinding[argLength + 2]; // append offending substitute and typeVariable
+ System.arraycopy(arguments, 0, augmentedArguments, 0, argLength);
+ augmentedArguments[argLength] = substitute;
+ augmentedArguments[argLength+1] = typeVariable;
+ return new ProblemMethodBinding(methodSubstitute, originalMethod.selector, augmentedArguments, ParameterBoundMismatch);
case TypeConstants.UNCHECKED :
// tolerate unchecked bounds
methodSubstitute.isUnchecked = true;
@@ -141,10 +136,21 @@
if (minArgLength < argLength) {
TypeBinding varargType = parameters[minArgLength]; // last arg type - as is ?
TypeBinding lastArgument = arguments[minArgLength];
- if (paramLength != argLength // argument is passed as is ?
- || (lastArgument != NullBinding
- && (lastArgument.dimensions() == 0 || lastArgument.leafComponentType().isBaseType() != varargType.leafComponentType().isBaseType()))) {
- varargType = ((ArrayBinding)varargType).elementsType(); // eliminate one array dimension
+ checkVarargDimension: {
+ if (paramLength == argLength) {
+ if (lastArgument == NullBinding) break checkVarargDimension;
+ switch (lastArgument.dimensions()) {
+ case 0 :
+ break; // will remove one dim
+ case 1 :
+ if (!lastArgument.leafComponentType().isBaseType()) break checkVarargDimension;
+ break; // will remove one dim
+ default :
+ break checkVarargDimension;
+ }
+ }
+ // eliminate one array dimension
+ varargType = ((ArrayBinding)varargType).elementsType();
}
for (int i = minArgLength; i < argLength; i++) {
varargType.collectSubstitutes(scope, arguments[i], collectedSubstitutes, CONSTRAINT_EXTENDS);
@@ -201,6 +207,18 @@
TypeBinding equalSubstitute = equalSubstitutes[j];
if (equalSubstitute == null) continue nextConstraint;
// if (equalSubstitute == current) continue nextConstraint;
+ if (equalSubstitute == current) {
+ // try to find a better different match if any in subsequent equal candidates
+ for (int k = j+1; k < equalLength; k++) {
+ equalSubstitute = equalSubstitutes[k];
+ if (equalSubstitute != current && equalSubstitute != null) {
+ substitutes[i] = equalSubstitute;
+ continue nextTypeParameter;
+ }
+ }
+ substitutes[i] = current;
+ continue nextTypeParameter;
+ }
// if (equalSubstitute.isTypeVariable()) {
// TypeVariableBinding variable = (TypeVariableBinding) equalSubstitute;
// // substituted by a variable of the same method, ignore
@@ -264,7 +282,7 @@
int length = originalVariables.length;
TypeBinding[] rawArguments = new TypeBinding[length];
for (int i = 0; i < length; i++) {
- rawArguments[i] = originalVariables[i].erasure();
+ rawArguments[i] = originalVariables[i].upperBound();
}
this.isRaw = true;
this.isUnchecked = false;
@@ -310,19 +328,19 @@
/*
* parameterizedDeclaringUniqueKey dot selector originalMethodGenericSignature percent typeArguments
- * p.X<U> { <T> void bar(T t, U u) { new X<String>().bar(this, "") } } --> Lp/X<Ljava/lang/String;>;.bar<T:Ljava/lang/Object;>(TT;TU;)V^123%<Lp/X;>
+ * p.X<U> { <T> void bar(T t, U u) { new X<String>().bar(this, "") } } --> Lp/X<Ljava/lang/String;>;.bar<T:Ljava/lang/Object;>(TT;Ljava/lang/String;)V%<Lp/X;>
*/
- public char[] computeUniqueKey(boolean withAccessFlags) {
- if (this.isRaw)
- return super.computeUniqueKey(withAccessFlags);
+ public char[] computeUniqueKey(boolean isLeaf) {
StringBuffer buffer = new StringBuffer();
- buffer.append(super.computeUniqueKey(withAccessFlags));
+ buffer.append(this.originalMethod.computeUniqueKey(false/*not a leaf*/));
buffer.append('%');
buffer.append('<');
- int length = this.typeArguments.length;
- for (int i = 0; i < length; i++) {
- TypeBinding typeArgument = this.typeArguments[i];
- buffer.append(typeArgument.computeUniqueKey(false/*without access flags*/));
+ if (!this.isRaw) {
+ int length = this.typeArguments.length;
+ for (int i = 0; i < length; i++) {
+ TypeBinding typeArgument = this.typeArguments[i];
+ buffer.append(typeArgument.computeUniqueKey(false/*not a leaf*/));
+ }
}
buffer.append('>');
int resultLength = buffer.length();
@@ -368,19 +386,28 @@
computeSubstitutes: {
// infer from expected return type
if (expectedType != null) {
- returnType.collectSubstitutes(scope, expectedType, collectedSubstitutes, CONSTRAINT_SUPER);
+ this.returnType.collectSubstitutes(scope, expectedType, collectedSubstitutes, CONSTRAINT_SUPER);
}
// infer from bounds of type parameters
for (int i = 0; i < varLength; i++) {
TypeVariableBinding originalVariable = originalVariables[i];
TypeBinding argument = this.typeArguments[i];
+ boolean argAlreadyInferred = argument != originalVariable;
if (originalVariable.firstBound == originalVariable.superclass) {
- Scope.substitute(this, originalVariable.firstBound) // substitue original bound with resolved variables
- .collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS);
+ TypeBinding substitutedBound = Scope.substitute(this, originalVariable.superclass);
+ argument.collectSubstitutes(scope, substitutedBound, collectedSubstitutes, CONSTRAINT_SUPER);
+ // JLS 15.12.2.8 claims reverse inference shouldn't occur, however it improves inference
+ // e.g. given: <E extends Object, S extends Collection<E>> S test1(S param)
+ // invocation: test1(new Vector<String>()) will infer: S=Vector<String> and with code below: E=String
+ if (argAlreadyInferred)
+ substitutedBound.collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS);
}
for (int j = 0, max = originalVariable.superInterfaces.length; j < max; j++) {
- Scope.substitute(this, originalVariable.superInterfaces[j]) // substitue original bound with resolved variables
- .collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS);
+ TypeBinding substitutedBound = Scope.substitute(this, originalVariable.superInterfaces[j]);
+ argument.collectSubstitutes(scope, substitutedBound, collectedSubstitutes, CONSTRAINT_SUPER);
+ // JLS 15.12.2.8 claims reverse inference shouldn't occur, however it improves inference
+ if (argAlreadyInferred)
+ substitutedBound.collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS);
}
}
substitutes = resolveSubstituteConstraints(scope, originalVariables, substitutes, true/*consider Ti<:Uk*/, collectedSubstitutes);
@@ -391,7 +418,7 @@
this.isRaw = true;
this.isUnchecked = false;
for (int i = 0; i < varLength; i++) {
- this.typeArguments[i] = originalVariables[i].erasure();
+ this.typeArguments[i] = originalVariables[i].upperBound();
}
break computeSubstitutes;
}
@@ -402,7 +429,7 @@
this.typeArguments[i] = substitutes[i];
} else {
// remaining unresolved variable are considered to be Object (or their bound actually)
- this.typeArguments[i] = originalVariables[i].erasure();
+ this.typeArguments[i] = originalVariables[i].upperBound();
}
}
}
@@ -443,7 +470,7 @@
*/
public MethodBinding tiebreakMethod() {
if (this.tiebreakMethod == null) {
- this.tiebreakMethod = new ParameterizedGenericMethodBinding(this.originalMethod, (RawTypeBinding)null, this.environment);
+ this.tiebreakMethod = this.isRaw ? this : new ParameterizedGenericMethodBinding(this.originalMethod, (RawTypeBinding)null, this.environment);
}
return this.tiebreakMethod;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
index d3e82eb..0bdbc4c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
@@ -75,11 +75,14 @@
for (int i = 0; i < length; i++) {
TypeVariableBinding originalVariable = originalVariables[i];
TypeVariableBinding substitutedVariable = substitutedVariables[i];
- substitutedVariable.superclass = (ReferenceBinding) Scope.substitute(substitution, originalVariable.superclass);
+ TypeBinding substitutedSuperclass = Scope.substitute(substitution, originalVariable.superclass);
+ substitutedVariable.superclass = (ReferenceBinding) (substitutedSuperclass.isArrayType()
+ ? parameterizedDeclaringClass.environment.getType(JAVA_LANG_OBJECT)
+ : substitutedSuperclass);
substitutedVariable.superInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces);
if (originalVariable.firstBound != null) {
substitutedVariable.firstBound = originalVariable.firstBound == originalVariable.superclass
- ? substitutedVariable.superclass
+ ? substitutedSuperclass // could be array type
: substitutedVariable.superInterfaces[0];
}
}
@@ -95,14 +98,6 @@
// no init
}
- /*
- * parameterizedDeclaringUniqueKey dot selector originalMethodGenericSignature
- * p.X<U> { void bar(U u) { new X<String>().bar("") } } --> Lp/X<Ljava/lang/String;>;.bar(TU;)V^123
- */
- public char[] computeUniqueKey(boolean withAccessFlags) {
- return computeUniqueKey(original(), withAccessFlags);
- }
-
/**
* The type of x.getClass() is substituted from 'Class<? extends Object>' into: 'Class<? extends |X|> where |X| is X's erasure.
*/
@@ -116,7 +111,7 @@
method.parameters = originalMethod.parameters;
method.thrownExceptions = originalMethod.thrownExceptions;
ReferenceBinding genericClassType = scope.getJavaLangClass();
- method.returnType = scope.createParameterizedType(
+ method.returnType = scope.environment().createParameterizedType(
genericClassType,
new TypeBinding[] { scope.environment().createWildcard(genericClassType, 0, receiverType.erasure(), null /*no extra bound*/, Wildcard.EXTENDS) },
null);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
index 1217d4c..3dcf439 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
@@ -12,6 +12,7 @@
import java.util.Map;
import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
/**
@@ -33,9 +34,8 @@
public ParameterizedTypeBinding(ReferenceBinding type, TypeBinding[] arguments, ReferenceBinding enclosingType, LookupEnvironment environment){
this.environment = environment;
- initialize(type, arguments);
this.enclosingType = enclosingType; // never unresolved, never lazy per construction
-
+ initialize(type, arguments);
if (type instanceof UnresolvedReferenceBinding)
((UnresolvedReferenceBinding) type).addWrapper(this);
if (arguments != null) {
@@ -47,6 +47,25 @@
}
/**
+ * Iterate type arguments, and validate them according to corresponding variable bounds.
+ */
+ public void boundCheck(Scope scope, TypeReference[] argumentReferences) {
+ if ((this.tagBits & PassedBoundCheck) == 0) {
+ boolean hasErrors = false;
+ TypeVariableBinding[] typeVariables = this.type.typeVariables();
+ if (this.arguments != null && typeVariables != null) { // arguments may be null in error cases
+ for (int i = 0, length = typeVariables.length; i < length; i++) {
+ if (typeVariables[i].boundCheck(this, this.arguments[i]) != TypeConstants.OK) {
+ hasErrors = true;
+ scope.problemReporter().typeMismatchError(this.arguments[i], typeVariables[i], this.type, argumentReferences[i]);
+ }
+ }
+ }
+ if (!hasErrors) this.tagBits |= PassedBoundCheck; // no need to recheck it in the future
+ }
+ }
+
+ /**
* @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#canBeInstantiated()
*/
public boolean canBeInstantiated() {
@@ -57,26 +76,36 @@
}
/**
* Perform capture conversion for a parameterized type with wildcard arguments
- * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#capture()
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#capture(Scope,int)
*/
- public TypeBinding capture() {
- TypeBinding[] originalArguments = arguments, capturedArguments = originalArguments;
- if ((this.tagBits & TagBits.HasDirectWildcard) != 0) {
- int length = originalArguments.length;
- capturedArguments = new TypeBinding[length];
- for (int i = 0; i < length; i++) {
- TypeBinding argument = originalArguments[i];
- if (argument.kind() == Binding.WILDCARD_TYPE) {
- capturedArguments[i] = new CaptureBinding((WildcardBinding) argument);
- } else {
- capturedArguments[i] = argument;
- }
+ public TypeBinding capture(Scope scope, int position) {
+ if ((this.tagBits & TagBits.HasDirectWildcard) == 0)
+ return this;
+
+ TypeBinding[] originalArguments = arguments;
+ int length = originalArguments.length;
+ TypeBinding[] capturedArguments = new TypeBinding[length];
+
+ // Retrieve the type context for capture bindingKey
+ ReferenceBinding contextType = scope.enclosingSourceType();
+ if (contextType != null) contextType = contextType.outermostEnclosingType(); // maybe null when used programmatically by DOM
+
+ for (int i = 0; i < length; i++) {
+ TypeBinding argument = originalArguments[i];
+ if (argument.kind() == Binding.WILDCARD_TYPE && ((WildcardBinding)argument).otherBounds == null) { // no capture for intersection types
+ capturedArguments[i] = new CaptureBinding((WildcardBinding) argument, contextType, position);
+ } else {
+ capturedArguments[i] = argument;
}
}
- if (capturedArguments != originalArguments) {
- return this.environment.createParameterizedType(this.type, capturedArguments, enclosingType());
+ ParameterizedTypeBinding capturedParameterizedType = this.environment.createParameterizedType(this.type, capturedArguments, enclosingType());
+ for (int i = 0; i < length; i++) {
+ TypeBinding argument = capturedArguments[i];
+ if (argument.isCapture()) {
+ ((CaptureBinding)argument).initializeBounds(capturedParameterizedType);
+ }
}
- return this;
+ return capturedParameterizedType;
}
/**
* Collect the substitutes into a map for certain type variables inside the receiver type
@@ -94,12 +123,12 @@
case CONSTRAINT_EQUAL :
case CONSTRAINT_EXTENDS :
equivalent = this;
- otherEquivalent = ((ReferenceBinding)otherType).findSuperTypeErasingTo((ReferenceBinding)this.type.erasure());
+ otherEquivalent = ((ReferenceBinding)otherType).findSuperTypeWithSameErasure(this.type);
if (otherEquivalent == null) return;
break;
case CONSTRAINT_SUPER :
default:
- equivalent = this.findSuperTypeErasingTo((ReferenceBinding)(otherType.erasure()));
+ equivalent = this.findSuperTypeWithSameErasure(otherType);
if (equivalent == null) return;
otherEquivalent = (ReferenceBinding) otherType;
break;
@@ -145,10 +174,10 @@
this.id = NoId;
}
- public char[] computeUniqueKey(boolean withAccessFlags) {
+ public char[] computeUniqueKey(boolean isLeaf) {
StringBuffer sig = new StringBuffer(10);
if (this.isMemberType() && enclosingType().isParameterizedType()) {
- char[] typeSig = enclosingType().computeUniqueKey(false/*without access flags*/);
+ char[] typeSig = enclosingType().computeUniqueKey(false/*not a leaf*/);
for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); // copy all but trailing semicolon
sig.append('.').append(sourceName());
} else if(this.type.isLocalType()){
@@ -157,26 +186,32 @@
ReferenceBinding temp;
while ((temp = enclosing.enclosingType()) != null)
enclosing = temp;
- char[] typeSig = enclosing.signature();
+ char[] typeSig = enclosing.computeUniqueKey(false/*not a leaf*/);
for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); // copy all but trailing semicolon
sig.append('$');
sig.append(localTypeBinding.sourceStart);
} else {
- char[] typeSig = this.type.signature();
+ char[] typeSig = this.type.computeUniqueKey(false/*not a leaf*/);
for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); // copy all but trailing semicolon
- }
+ }
+ ReferenceBinding captureSourceType = null;
if (this.arguments != null) {
sig.append('<');
for (int i = 0, length = this.arguments.length; i < length; i++) {
- sig.append(this.arguments[i].computeUniqueKey(false/*without access flags*/));
+ TypeBinding typeBinding = this.arguments[i];
+ sig.append(typeBinding.computeUniqueKey(false/*not a leaf*/));
+ if (typeBinding instanceof CaptureBinding)
+ captureSourceType = ((CaptureBinding) typeBinding).sourceType;
}
sig.append('>'); //$NON-NLS-1$
}
sig.append(';');
- if (withAccessFlags) {
- sig.append('^');
- sig.append(getAccessFlags());
+ if (captureSourceType != null && captureSourceType != this.type) {
+ // contains a capture binding
+ sig.insert(0, "&"); //$NON-NLS-1$
+ sig.insert(0, captureSourceType.computeUniqueKey(false/*not a leaf*/));
}
+
int sigLength = sig.length();
char[] uniqueKey = new char[sigLength];
sig.getChars(0, sigLength, uniqueKey, 0);
@@ -215,12 +250,6 @@
* @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#enclosingType()
*/
public ReferenceBinding enclosingType() {
- if (this.isMemberType() && this.enclosingType == null) {
- ReferenceBinding originalEnclosing = this.type.enclosingType();
- this.enclosingType = originalEnclosing.isGenericType()
- ? this.environment.createRawType(originalEnclosing, originalEnclosing.enclosingType()) // TODO (need to propagate in depth on enclosing type)
- : originalEnclosing;
- }
return this.enclosingType;
}
@@ -502,7 +531,12 @@
// this.superInterfaces = null;
// this.fields = null;
// this.methods = null;
- this.modifiers = someType.modifiers | AccGenericSignature;
+ this.modifiers = someType.modifiers;
+ // only set AccGenericSignature if parameterized or have enclosing type required signature
+ if (someArguments != null)
+ this.modifiers |= AccGenericSignature;
+ else if (this.enclosingType != null)
+ this.modifiers |= (this.enclosingType.modifiers & AccGenericSignature);
if (someArguments != null) {
this.arguments = someArguments;
for (int i = 0, length = someArguments.length; i < length; i++) {
@@ -536,15 +570,20 @@
return ((WildcardBinding) otherType).boundCheck(this);
case Binding.PARAMETERIZED_TYPE :
- if ((otherType.tagBits & HasDirectWildcard) == 0 && (!this.isMemberType() || !otherType.isMemberType()))
- return false; // should have been identical
ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
if (this.type != otherParamType.type)
return false;
if (!isStatic()) { // static member types do not compare their enclosing
- ReferenceBinding enclosing = enclosingType();
- if (enclosing != null && !enclosing.isEquivalentTo(otherParamType.enclosingType()))
- return false;
+ ReferenceBinding enclosing = enclosingType();
+ if (enclosing != null) {
+ ReferenceBinding otherEnclosing = otherParamType.enclosingType();
+ if (otherEnclosing == null) return false;
+ if ((otherEnclosing.tagBits & HasDirectWildcard) == 0) {
+ if (enclosing != otherEnclosing) return false;
+ } else {
+ if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false;
+ }
+ }
}
int length = this.arguments == null ? 0 : this.arguments.length;
TypeBinding[] otherArguments = otherParamType.arguments;
@@ -563,6 +602,73 @@
return false;
}
+ public boolean isIntersectingWith(TypeBinding otherType) {
+ if (this == otherType)
+ return true;
+ if (otherType == null)
+ return false;
+ switch(otherType.kind()) {
+
+ case Binding.PARAMETERIZED_TYPE :
+ ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
+ if (this.type != otherParamType.type)
+ return false;
+ if (!isStatic()) { // static member types do not compare their enclosing
+ ReferenceBinding enclosing = enclosingType();
+ if (enclosing != null) {
+ ReferenceBinding otherEnclosing = otherParamType.enclosingType();
+ if (otherEnclosing == null) return false;
+ if ((otherEnclosing.tagBits & HasDirectWildcard) == 0) {
+ if (enclosing != otherEnclosing) return false;
+ } else {
+ if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false;
+ }
+ }
+ }
+ int length = this.arguments == null ? 0 : this.arguments.length;
+ TypeBinding[] otherArguments = otherParamType.arguments;
+ int otherLength = otherArguments == null ? 0 : otherArguments.length;
+ if (otherLength != length)
+ return false;
+ for (int i = 0; i < length; i++) {
+ if (!this.arguments[i].isTypeArgumentIntersecting(otherArguments[i]))
+ return false;
+ }
+ return true;
+
+ case Binding.GENERIC_TYPE :
+ SourceTypeBinding otherGenericType = (SourceTypeBinding) otherType;
+ if (this.type != otherGenericType)
+ return false;
+ if (!isStatic()) { // static member types do not compare their enclosing
+ ReferenceBinding enclosing = enclosingType();
+ if (enclosing != null) {
+ ReferenceBinding otherEnclosing = otherGenericType.enclosingType();
+ if (otherEnclosing == null) return false;
+ if ((otherEnclosing.tagBits & HasDirectWildcard) == 0) {
+ if (enclosing != otherEnclosing) return false;
+ } else {
+ if (!enclosing.isEquivalentTo(otherGenericType.enclosingType())) return false;
+ }
+ }
+ }
+ length = this.arguments == null ? 0 : this.arguments.length;
+ otherArguments = otherGenericType.typeVariables();
+ otherLength = otherArguments == null ? 0 : otherArguments.length;
+ if (otherLength != length)
+ return false;
+ for (int i = 0; i < length; i++) {
+ if (!this.arguments[i].isTypeArgumentIntersecting(otherArguments[i]))
+ return false;
+ }
+ return true;
+
+ case Binding.RAW_TYPE :
+ return erasure() == otherType.erasure();
+ }
+ return false;
+ }
+
/**
* @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isParameterizedType()
*/
@@ -586,9 +692,12 @@
ReferenceBinding[] originalMemberTypes = this.type.memberTypes();
int length = originalMemberTypes.length;
ReferenceBinding[] parameterizedMemberTypes = new ReferenceBinding[length];
+ // boolean isRaw = this.isRawType();
for (int i = 0; i < length; i++)
// substitute all member types, so as to get updated enclosing types
- parameterizedMemberTypes[i] = this.environment.createParameterizedType(originalMemberTypes[i], null, this);
+ parameterizedMemberTypes[i] = /*isRaw && originalMemberTypes[i].isGenericType()
+ ? this.environment.createRawType(originalMemberTypes[i], this)
+ : */ this.environment.createParameterizedType(originalMemberTypes[i], null, this);
this.memberTypes = parameterizedMemberTypes;
} finally {
// if the original fields cannot be retrieved (ex. AbortCompilation), then assume we do not have any fields
@@ -673,14 +782,14 @@
} else if (argLength != refTypeVariables.length) { // check arity
this.environment.problemReporter.incorrectArityForParameterizedType(null, resolvedType, this.arguments);
return this; // cannot reach here as AbortCompilation is thrown
- }
- // check argument type compatibility
- for (int i = 0; i < argLength; i++) {
- TypeBinding resolvedArgument = this.arguments[i];
- if (refTypeVariables[i].boundCheck(this, resolvedArgument) != TypeConstants.OK) {
- this.environment.problemReporter.typeMismatchError(resolvedArgument, refTypeVariables[i], resolvedType, null);
- }
}
+ // check argument type compatibility... REMOVED for now since incremental build will propagate change & detect in source
+// for (int i = 0; i < argLength; i++) {
+// TypeBinding resolvedArgument = this.arguments[i];
+// if (refTypeVariables[i].boundCheck(this, resolvedArgument) != TypeConstants.OK) {
+// this.environment.problemReporter.typeMismatchError(resolvedArgument, refTypeVariables[i], resolvedType, null);
+// }
+// }
}
return this;
}
@@ -781,11 +890,15 @@
if (this.type == unresolvedType) {
this.type = resolvedType; // cannot be raw since being parameterized below
update = true;
+ ReferenceBinding enclosing = resolvedType.enclosingType();
+ if (enclosing != null) {
+ this.enclosingType = (ReferenceBinding) env.convertToRawType(enclosing); // needed when binding unresolved member type
+ }
}
if (this.arguments != null) {
for (int i = 0, l = this.arguments.length; i < l; i++) {
if (this.arguments[i] == unresolvedType) {
- this.arguments[i] = resolvedType.isGenericType() ? env.createRawType(resolvedType, resolvedType.enclosingType()) : resolvedType;
+ this.arguments[i] = env.convertToRawType(resolvedType);
update = true;
}
}
@@ -828,7 +941,10 @@
if (isStatic() && isNestedType()) buffer.append("static "); //$NON-NLS-1$
if (isFinal()) buffer.append("final "); //$NON-NLS-1$
- buffer.append(isInterface() ? "interface " : "class "); //$NON-NLS-1$ //$NON-NLS-2$
+ if (isEnum()) buffer.append("enum "); //$NON-NLS-1$
+ else if (isAnnotationType()) buffer.append("@interface "); //$NON-NLS-1$
+ else if (isClass()) buffer.append("class "); //$NON-NLS-1$
+ else buffer.append("interface "); //$NON-NLS-1$
buffer.append(this.debugName());
buffer.append("\n\textends "); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
index 0410c5c..f0cf4a1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
@@ -18,8 +18,8 @@
// NOTE: must only answer the subset of the name related to the problem
-public ProblemFieldBinding(ReferenceBinding declaringClass, char[][] compoundName, int problemId) {
- this(null, declaringClass, CharOperation.concatWith(compoundName, '.'), problemId);
+public ProblemFieldBinding(FieldBinding closestMatch, char[][] compoundName, int problemId) {
+ this(closestMatch, closestMatch == null ? null : closestMatch.declaringClass, CharOperation.concatWith(compoundName, '.'), problemId);
}
public ProblemFieldBinding(ReferenceBinding declaringClass, char[] name, int problemId) {
this(null, declaringClass, name, problemId);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java
index a4a3985..8da32b1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java
@@ -11,26 +11,18 @@
package org.eclipse.jdt.internal.compiler.lookup;
public class ProblemReferenceBinding extends ReferenceBinding {
- public ReferenceBinding original;
+ public ReferenceBinding closestMatch;
private int problemReason;
- public ReferenceBinding alternateMatch;
// NOTE: must only answer the subset of the name related to the problem
-public ProblemReferenceBinding(char[][] compoundName, int problemReason) {
- this(compoundName, null, problemReason);
-}
-public ProblemReferenceBinding(char[] name, int problemReason) {
- this(new char[][] {name}, null, problemReason);
-}
-
-public ProblemReferenceBinding(char[][] compoundName, ReferenceBinding original, int problemReason) {
+public ProblemReferenceBinding(char[][] compoundName, ReferenceBinding closestMatch, int problemReason) {
this.compoundName = compoundName;
- this.original = original;
+ this.closestMatch = closestMatch;
this.problemReason = problemReason;
}
-public ProblemReferenceBinding(char[] name, ReferenceBinding original, int problemReason) {
- this(new char[][] {name}, original, problemReason);
+public ProblemReferenceBinding(char[] name, ReferenceBinding closestMatch, int problemReason) {
+ this(new char[][] {name}, closestMatch, problemReason);
}
/* API
* Answer the problem id associated with the receiver.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
index 352de0d..06f5a68 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
@@ -30,20 +30,17 @@
this.modifiers &= ~AccGenericSignature; // only need signature if enclosing needs one
}
- public char[] computeUniqueKey(boolean withAccessFlags) {
+ public char[] computeUniqueKey(boolean isLeaf) {
StringBuffer sig = new StringBuffer(10);
if (isMemberType() && enclosingType().isParameterizedType()) {
- char[] typeSig = enclosingType().computeUniqueKey(false/*without access flags*/);
+ char[] typeSig = enclosingType().computeUniqueKey(false/*not a leaf*/);
for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); // copy all but trailing semicolon
sig.append('.').append(sourceName()).append('<').append('>').append(';');
} else {
- sig.append(this.type.signature()); // erasure
+ sig.append(this.type.computeUniqueKey(false/*not a leaf*/));
sig.insert(sig.length()-1, "<>"); //$NON-NLS-1$
}
- if (withAccessFlags) {
- sig.append('^');
- sig.append(getAccessFlags());
- }
+
int sigLength = sig.length();
char[] uniqueKey = new char[sigLength];
sig.getChars(0, sigLength, uniqueKey, 0);
@@ -112,6 +109,22 @@
}
return false;
}
+
+ public boolean isIntersectingWith(TypeBinding otherType) {
+ if (this == otherType)
+ return true;
+ if (otherType == null)
+ return false;
+ switch(otherType.kind()) {
+
+ case Binding.GENERIC_TYPE :
+ case Binding.PARAMETERIZED_TYPE :
+ case Binding.RAW_TYPE :
+ return erasure() == otherType.erasure();
+ }
+ return false;
+ }
+
/**
* Raw type is not treated as a standard parameterized type
* @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isParameterizedType()
@@ -128,7 +141,8 @@
int length = typeVariables.length;
TypeBinding[] typeArguments = new TypeBinding[length];
for (int i = 0; i < length; i++) {
- typeArguments[i] = typeVariables[i].erasure();
+ // perform raw conversion on variable upper bound - could cause infinite regression if arguments were initialized lazily
+ typeArguments[i] = this.environment.convertToRawType(typeVariables[i].erasure());
}
this.arguments = typeArguments;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
index 2b3456f..1d67eea 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
@@ -87,7 +87,7 @@
if (declaringClass == null) return false; // could be null if incorrect top-level protected type
//int depth = 0;
do {
- if (currentType.findSuperTypeErasingTo(declaringErasure) != null) return true;
+ if (currentType.findSuperTypeWithSameErasure(declaringErasure) != null) return true;
//depth++;
currentType = currentType.enclosingType();
} while (currentType != null);
@@ -199,24 +199,38 @@
return invocationType.fPackage == fPackage;
}
public char[] computeGenericTypeSignature(TypeVariableBinding[] typeVariables) {
- if (typeVariables == NoTypeVariables) {
- return signature();
- } else {
- char[] typeSig = signature();
- StringBuffer sig = new StringBuffer(10);
+
+ boolean isMemberOfGeneric = isMemberType() && (enclosingType().modifiers & AccGenericSignature) != 0;
+ if (typeVariables == NoTypeVariables && !isMemberOfGeneric) {
+ return signature();
+ }
+ StringBuffer sig = new StringBuffer(10);
+ if (isMemberOfGeneric) {
+ char[] typeSig = enclosingType().genericTypeSignature();
for (int i = 0; i < typeSig.length-1; i++) { // copy all but trailing semicolon
sig.append(typeSig[i]);
}
+ sig.append('.'); // NOTE: cannot override trailing ';' with '.' in enclosing signature, since shared char[]
+ sig.append(this.sourceName);
+ } else {
+ char[] typeSig = signature();
+ for (int i = 0; i < typeSig.length-1; i++) { // copy all but trailing semicolon
+ sig.append(typeSig[i]);
+ }
+ }
+ if (typeVariables == NoTypeVariables) {
+ sig.append(';');
+ } else {
sig.append('<');
for (int i = 0, length = typeVariables.length; i < length; i++) {
sig.append(typeVariables[i].genericTypeSignature());
}
sig.append(">;"); //$NON-NLS-1$
- int sigLength = sig.length();
- char[] result = new char[sigLength];
- sig.getChars(0, sigLength, result, 0);
- return result;
- }
+ }
+ int sigLength = sig.length();
+ char[] result = new char[sigLength];
+ sig.getChars(0, sigLength, result, 0);
+ return result;
}
public void computeId() {
@@ -301,6 +315,10 @@
else if (CharOperation.equals(typeName, JAVA_LANG_OVERRIDE[2]))
id = T_JavaLangOverride;
return;
+ case 'R' :
+ if (CharOperation.equals(typeName, JAVA_LANG_RUNTIMEEXCEPTION[2]))
+ id = T_JavaLangRuntimeException;
+ break;
case 'S' :
if (CharOperation.equals(typeName, JAVA_LANG_STRING[2]))
id = T_JavaLangString;
@@ -373,28 +391,11 @@
}
}
/*
- * p.X<T extends Y & I, U extends Y> {} -> Lp/X<TT;TU;>;^123
+ * p.X<T extends Y & I, U extends Y> {} -> Lp/X<TT;TU;>;
*/
-public char[] computeUniqueKey(boolean withAccessFlags) {
- // generic type signature
- char[] genericSignature = genericTypeSignature();
- int sigLength = genericSignature.length;
-
- if (!withAccessFlags) return genericSignature;
-
- // flags
- String flags = Integer.toString(getAccessFlags());
- int flagsLength = flags.length();
-
- // unique key
- char[] uniqueKey = new char[sigLength + 1 + flagsLength];
- int index = 0;
- System.arraycopy(genericSignature, 0, uniqueKey, index, sigLength);
- index += sigLength;
- uniqueKey[index++] = '^';
- flags.getChars(0, flagsLength, uniqueKey, index);
-
- return uniqueKey;
+public char[] computeUniqueKey(boolean isLeaf) {
+ if (!isLeaf) return signature();
+ return genericTypeSignature();
}
/* Answer the receiver's constant pool name.
*
@@ -461,14 +462,16 @@
* same id though being distincts.
*
*/
-public ReferenceBinding findSuperTypeErasingTo(int erasureId, boolean erasureIsClass) {
+public ReferenceBinding findSuperTypeErasingTo(int wellKnownErasureID, boolean erasureIsClass) {
- if (this.id == erasureId || erasure().id == erasureId) return this;
+ // do not allow type variables to match with erasures for free
+ if (this.id == wellKnownErasureID || (!isTypeVariable() && erasure().id == wellKnownErasureID)) return this;
+
ReferenceBinding currentType = this;
// iterate superclass to avoid recording interfaces if searched supertype is class
if (erasureIsClass) {
while ((currentType = currentType.superclass()) != null) {
- if (currentType.id == erasureId || currentType.erasure().id == erasureId) return currentType;
+ if (currentType.id == wellKnownErasureID || (!currentType.isTypeVariable() && currentType.erasure().id == wellKnownErasureID)) return currentType;
}
return null;
}
@@ -486,7 +489,7 @@
for (int i = 0; i <= lastPosition; i++) {
ReferenceBinding[] interfaces = interfacesToVisit[i];
for (int j = 0, length = interfaces.length; j < length; j++) {
- if ((currentType = interfaces[j]).id == erasureId || currentType.erasure().id == erasureId)
+ if ((currentType = interfaces[j]).id == wellKnownErasureID || (!currentType.isTypeVariable() && currentType.erasure().id == wellKnownErasureID))
return currentType;
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
@@ -499,16 +502,20 @@
}
return null;
}
+
/**
* Find supertype which erases to a given type, or null if not found
*/
-public ReferenceBinding findSuperTypeErasingTo(ReferenceBinding erasure) {
+public ReferenceBinding findSuperTypeWithSameErasure(TypeBinding otherType) {
- if (this == erasure || erasure() == erasure) return this;
+ // do not allow type variables to match with erasures for free
+ if (!otherType.isTypeVariable()) otherType = otherType.erasure();
+ if (this == otherType || (!isTypeVariable() && erasure() == otherType)) return this;
+
ReferenceBinding currentType = this;
- if (!erasure.isInterface()) {
+ if (!otherType.isInterface()) {
while ((currentType = currentType.superclass()) != null) {
- if (currentType == erasure || currentType.erasure() == erasure) return currentType;
+ if (currentType == otherType || (!currentType.isTypeVariable() && currentType.erasure() == otherType)) return currentType;
}
return null;
}
@@ -526,7 +533,7 @@
for (int i = 0; i <= lastPosition; i++) {
ReferenceBinding[] interfaces = interfacesToVisit[i];
for (int j = 0, length = interfaces.length; j < length; j++) {
- if ((currentType = interfaces[j]) == erasure || currentType.erasure() == erasure)
+ if ((currentType = interfaces[j]) == otherType || (!currentType.isTypeVariable() && currentType.erasure() == otherType))
return currentType;
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
@@ -602,6 +609,52 @@
return (modifiers & AccRestrictedAccess) != 0;
}
+/**
+ * Returns true if the two types have an incompatible common supertype,
+ * e.g. List<String> and List<Integer>
+ */
+public boolean hasIncompatibleSuperType(ReferenceBinding otherType) {
+
+ if (this == otherType) return false;
+
+ ReferenceBinding currentType = this;
+ ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
+ ReferenceBinding match;
+ int lastPosition = -1;
+ do {
+ match = otherType.findSuperTypeWithSameErasure(currentType);
+ if (match != null) {
+ if (!match.isIntersectingWith(currentType))
+ return true;
+ }
+ ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+ if (itsInterfaces != NoSuperInterfaces) {
+ if (++lastPosition == interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
+ interfacesToVisit[lastPosition] = itsInterfaces;
+ }
+ } while ((currentType = currentType.superclass()) != null);
+
+ for (int i = 0; i <= lastPosition; i++) {
+ ReferenceBinding[] interfaces = interfacesToVisit[i];
+ for (int j = 0, length = interfaces.length; j < length; j++) {
+ if ((currentType = interfaces[j]) == otherType) return false;
+ match = otherType.findSuperTypeWithSameErasure(currentType);
+ if (match != null) {
+ if (!match.isIntersectingWith(currentType))
+ return true;
+ }
+ ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+ if (itsInterfaces != NoSuperInterfaces) {
+ if (++lastPosition == interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
+ interfacesToVisit[lastPosition] = itsInterfaces;
+ }
+ }
+ }
+ return false;
+}
+
/* Answer true if the receiver implements anInterface or is identical to anInterface.
* If searchHierarchy is true, then also search the receiver's superclasses.
*
@@ -661,9 +714,6 @@
public boolean isAnnotationType() {
return (modifiers & AccAnnotation) != 0;
}
-public final boolean isAnonymousType() {
- return (tagBits & IsAnonymousType) != 0;
-}
public final boolean isBinaryBinding() {
return (tagBits & IsBinaryBinding) != 0;
}
@@ -694,14 +744,23 @@
// check compatibility with capture of ? super X
if (otherType.isCapture()) {
CaptureBinding otherCapture = (CaptureBinding) otherType;
- if (otherCapture.lowerBound != null) {
- return this.isCompatibleWith(otherCapture.lowerBound);
+ TypeBinding otherLowerBound;
+ if ((otherLowerBound = otherCapture.lowerBound) != null) {
+ if (otherLowerBound.isArrayType()) return false;
+ return this.isCompatibleWith(otherLowerBound);
}
}
case Binding.GENERIC_TYPE :
case Binding.TYPE :
case Binding.PARAMETERIZED_TYPE :
case Binding.RAW_TYPE :
+ switch (this.kind()) {
+ case Binding.GENERIC_TYPE :
+ case Binding.PARAMETERIZED_TYPE :
+ case Binding.RAW_TYPE :
+ if (this.erasure() == otherType.erasure())
+ return false; // should have passed equivalence check above if same erasure
+ }
ReferenceBinding otherReferenceType = (ReferenceBinding) otherType;
if (otherReferenceType.isInterface()) // could be annotation type
return implementsInterface(otherReferenceType, true);
@@ -737,18 +796,6 @@
return (modifiers & AccInterface) != 0;
}
-public final boolean isPartOfRawType() {
- ReferenceBinding current = this;
- do {
- if (current.isRawType())
- return true;
- // no static type
- if (isStatic())
- break;
- } while ((current = current.enclosingType()) != null);
- return false;
-}
-
/* Answer true if the receiver has private visibility
*/
public final boolean isPrivate() {
@@ -757,8 +804,8 @@
/* Answer true if the receiver has private visibility and is used locally
*/
-public final boolean isPrivateUsed() {
- return (modifiers & AccPrivateUsed) != 0;
+public final boolean isUsed() {
+ return (modifiers & AccLocallyUsed) != 0;
}
/* Answer true if the receiver has protected visibility
*/
@@ -796,9 +843,39 @@
return false;
}
+/**
+ * JLS 11.5 ensures that Throwable, Exception, RuntimeException and Error are directly connected.
+ * (Throwable<- Exception <- RumtimeException, Throwable <- Error). Thus no need to check #isCompatibleWith
+ * but rather check in type IDs so as to avoid some eager class loading for JCL writers.
+ * When 'includeSupertype' is true, answers true if the given type can be a supertype of some unchecked exception
+ * type (i.e. Throwable or Exception).
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isUncheckedException(boolean)
+ */
+public boolean isUncheckedException(boolean includeSupertype) {
+ switch (this.id) {
+ case TypeIds.T_JavaLangError :
+ case TypeIds.T_JavaLangRuntimeException :
+ return true;
+ case TypeIds.T_JavaLangThrowable :
+ case TypeIds.T_JavaLangException :
+ return includeSupertype;
+ }
+ ReferenceBinding current = this;
+ while ((current = current.superclass()) != null) {
+ switch (current.id) {
+ case TypeIds.T_JavaLangError :
+ case TypeIds.T_JavaLangRuntimeException :
+ return true;
+ case TypeIds.T_JavaLangThrowable :
+ case TypeIds.T_JavaLangException :
+ return false;
+ }
+ }
+ return false;
+}
+
/* Answer true if the receiver is deprecated (or any of its enclosing types)
*/
-
public final boolean isViewedAsDeprecated() {
return (modifiers & (AccDeprecated | AccDeprecatedImplicitly)) != 0;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index 32000e8..160659a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -21,6 +21,7 @@
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
@@ -176,7 +177,10 @@
}
if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
identicalVariables: { // if substituted with original variables, then answer the generic type itself
- if (substitutedEnclosing != originalEnclosing) break identicalVariables;
+ if (substitutedEnclosing != null) {
+ //if (!(substitutedEnclosing instanceof SourceTypeBinding)) break identicalVariables;
+ if (substitutedEnclosing != originalEnclosing) break identicalVariables;
+ }
if (originalParameterizedType.type.isBinaryBinding()) break identicalVariables; // generic binary is never used as is, see 85262
TypeVariableBinding[] originalVariables = originalParameterizedType.type.typeVariables();
for (int i = 0, length = originalVariables.length; i < length; i++) {
@@ -215,23 +219,26 @@
if (!originalType.isMemberType()) break;
// fall thru in case enclosing is generic
case Binding.GENERIC_TYPE:
- ReferenceBinding originalGenericType = (ReferenceBinding) originalType;
+ ReferenceBinding originalReferenceType = (ReferenceBinding) originalType;
originalEnclosing = originalType.enclosingType();
substitutedEnclosing = originalEnclosing;
if (originalEnclosing != null) {
substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing);
}
if (substitution.isRawSubstitution()) {
- return substitution.environment().createRawType(originalGenericType, substitutedEnclosing);
+ return substitution.environment().createRawType(originalReferenceType, substitutedEnclosing);
}
- // treat as if parameterized with its type variables
- TypeVariableBinding[] originalVariables = originalGenericType.typeVariables();
- int length = originalVariables.length;
- System.arraycopy(originalVariables, 0, originalArguments = new TypeBinding[length], 0, length);
- substitutedArguments = substitute(substitution, originalArguments);
+ // treat as if parameterized with its type variables (non generic type gets 'null' arguments)
+ originalArguments = originalReferenceType.typeVariables();
+ if (originalArguments == NoTypeVariables) {
+ originalArguments = null;
+ substitutedArguments = null;
+ } else {
+ substitutedArguments = substitute(substitution, originalArguments);
+ }
if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
return substitution.environment().createParameterizedType(
- originalGenericType, substitutedArguments, substitutedEnclosing);
+ originalReferenceType, substitutedArguments, substitutedEnclosing);
}
break;
}
@@ -284,18 +291,6 @@
return null;
}
- /* Answer an int describing the relationship between the given type and unchecked exceptions.
- *
- * NotRelated
- * EqualOrMoreSpecific : type is known for sure to be an unchecked exception type
- * MoreGeneric : type is a supertype of an actual unchecked exception type
- */
- public int compareUncheckedException(ReferenceBinding type) {
- int comparison = compareTypes(type, getJavaLangRuntimeException());
- if (comparison != 0) return comparison;
- return compareTypes(type, getJavaLangError());
- }
-
public final CompilationUnitScope compilationUnitScope() {
Scope lastScope = null;
Scope scope = this;
@@ -307,6 +302,14 @@
}
/**
+ * Finds the most specific compiler options
+ */
+ public final CompilerOptions compilerOptions() {
+
+ return compilationUnitScope().environment.globalOptions;
+ }
+
+ /**
* Internal use only
* Given a method, returns null if arguments cannot be converted to parameters.
* Will answer a subsituted method in case the method was generic and type inference got triggered;
@@ -368,8 +371,9 @@
protected boolean connectTypeVariables(TypeParameter[] typeParameters) {
boolean noProblems = true;
- if (typeParameters == null || environment().options.sourceLevel < ClassFileConstants.JDK1_5) return true;
-
+ if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) return true;
+ TypeBinding[] types = new TypeBinding[2];
+ Map invocations = new HashMap(2);
nextVariable : for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) {
TypeParameter typeParameter = typeParameters[i];
TypeVariableBinding typeVariable = typeParameter.binding;
@@ -412,13 +416,11 @@
typeVariable.superclass = superRefType;
} else {
typeVariable.superInterfaces = new ReferenceBinding[] {superRefType};
- typeVariable.modifiers |= AccInterface;
}
typeVariable.firstBound = superRefType; // first bound used to compute erasure
-
TypeReference[] boundRefs = typeParameter.bounds;
if (boundRefs != null) {
- for (int j = 0, k = boundRefs.length; j < k; j++) {
+ for (int j = 0, boundLength = boundRefs.length; j < boundLength; j++) {
typeRef = boundRefs[j];
superType = this.kind == METHOD_SCOPE
? typeRef.resolveType((BlockScope)this, false)
@@ -429,6 +431,7 @@
continue nextVariable;
}
typeRef.resolvedType = superType; // hold onto the problem type
+ types[0] = superType;
if (superType.isArrayType()) {
problemReporter().boundCannotBeArray(typeRef, superType);
continue nextVariable;
@@ -440,27 +443,55 @@
noProblems = false;
continue nextVariable;
}
- if (superType.isParameterizedType()) {
- ReferenceBinding match = typeVariable.superclass.findSuperTypeErasingTo((ReferenceBinding) superType.erasure());
- boolean isCollision = match != null && match != superType;
- for (int index = typeVariable.superInterfaces.length; !isCollision && --index >= 0;) {
- ReferenceBinding temp = typeVariable.superInterfaces[index];
- isCollision = superType != temp && superType.erasure() == temp.erasure();
- }
- if (isCollision) {
- problemReporter().boundHasConflictingArguments(typeRef, superType);
- typeVariable.tagBits |= HierarchyHasProblems;
- noProblems = false;
- continue nextVariable;
+ // check against superclass
+ if (typeVariable.firstBound == typeVariable.superclass) {
+ types[1] = typeVariable.superclass;
+ TypeBinding[] mecs = minimalErasedCandidates(types, invocations);
+ if (mecs != null) {
+ nextCandidate: for (int k = 0, max = mecs.length; k < max; k++) {
+ TypeBinding mec = mecs[k];
+ if (mec == null) continue nextCandidate;
+ Set invalidInvocations = (Set)invocations.get(mec);
+ int invalidSize = invalidInvocations.size();
+ if (invalidSize > 1) {
+ TypeBinding[] collisions;
+ invalidInvocations.toArray(collisions = new TypeBinding[invalidSize]);
+ problemReporter().superinterfacesCollide(collisions[0].erasure(), typeRef, collisions[1], collisions[0]); // swap collisions since mec types got swapped
+ typeVariable.tagBits |= HierarchyHasProblems;
+ noProblems = false;
+ continue nextVariable;
+ }
+ }
}
}
+ // check against superinterfaces
for (int index = typeVariable.superInterfaces.length; --index >= 0;) {
- if (superType.erasure() == typeVariable.superInterfaces[index].erasure()) {
+ ReferenceBinding previousInterface = typeVariable.superInterfaces[index];
+ if (previousInterface == superRefType) {
problemReporter().duplicateBounds(typeRef, superType);
typeVariable.tagBits |= HierarchyHasProblems;
noProblems = false;
continue nextVariable;
}
+ types[1] = previousInterface;
+ invocations.clear();
+ TypeBinding[] mecs = minimalErasedCandidates(types, invocations);
+ if (mecs != null) {
+ nextCandidate: for (int m = 0, max = mecs.length; m < max; m++) {
+ TypeBinding mec = mecs[m];
+ if (mec == null) continue nextCandidate;
+ Set invalidInvocations = (Set)invocations.get(mec);
+ int invalidSize = invalidInvocations.size();
+ if (invalidSize > 1) {
+ TypeBinding[] collisions;
+ invalidInvocations.toArray(collisions = new TypeBinding[invalidSize]);
+ problemReporter().superinterfacesCollide(collisions[0].erasure(), typeRef, collisions[0], collisions[1]);
+ typeVariable.tagBits |= HierarchyHasProblems;
+ noProblems = false;
+ continue nextVariable;
+ }
+ }
+ }
}
int size = typeVariable.superInterfaces.length;
System.arraycopy(typeVariable.superInterfaces, 0, typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size);
@@ -471,89 +502,6 @@
return noProblems;
}
- public TypeBinding convertToRawType(TypeBinding type) {
-
- int dimension;
- TypeBinding originalType;
- switch(type.kind()) {
- case Binding.BASE_TYPE :
- case Binding.TYPE_PARAMETER:
- case Binding.WILDCARD_TYPE:
- case Binding.RAW_TYPE:
- return type;
- case Binding.ARRAY_TYPE:
- dimension = type.dimensions();
- originalType = type.leafComponentType();
- break;
- default:
- dimension = 0;
- originalType = type;
- }
- boolean needToConvert;
- switch (originalType.kind()) {
- case Binding.BASE_TYPE :
- return type;
- case Binding.GENERIC_TYPE :
- needToConvert = true;
- break;
- case Binding.PARAMETERIZED_TYPE :
- ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType;
- needToConvert = paramType.type.isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
- break;
- default :
- needToConvert = false;
- break;
- }
- ReferenceBinding originalEnclosing = originalType.enclosingType();
- TypeBinding convertedType;
- if (originalEnclosing == null) {
- convertedType = needToConvert ? environment().createRawType((ReferenceBinding)originalType.erasure(), null) : originalType;
- } else {
- ReferenceBinding convertedEnclosing;
- switch (originalEnclosing.kind()) {
- case Binding.GENERIC_TYPE :
- case Binding.PARAMETERIZED_TYPE :
- if (needToConvert || ((ReferenceBinding)originalType).isStatic()) {
- convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing);
- } else {
- convertedEnclosing = originalEnclosing;
- }
- break;
- default :
- convertedEnclosing = originalEnclosing;
- break;
- }
- if (needToConvert) {
- convertedType = environment().createRawType((ReferenceBinding) originalType.erasure(), convertedEnclosing);
- } else if (originalEnclosing != convertedEnclosing) {
- convertedType = createParameterizedType((ReferenceBinding) originalType.erasure(), null, convertedEnclosing);
- } else {
- convertedType = originalType;
- }
- }
- if (originalType != convertedType) {
- return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType;
- }
- return type;
- }
-// TypeBinding leafType = type.leafComponentType();
-// int dimension = type.dimensions();
-// ReferenceBinding originalEnclosing = leafType.enclosingType();
-// ReferenceBinding convertedEnclosing = originalEnclosing;
-// if (originalEnclosing != null && ((ReferenceBinding)leafType).isStatic()) {
-// convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing);
-// }
-// if (leafType.isGenericType()) {
-// type = environment().createRawType((ReferenceBinding) leafType, convertedEnclosing);
-// if (dimension > 0)
-// type = createArrayType(type, dimension);
-// } else if (originalEnclosing != convertedEnclosing) {
-// type = createParameterizedType((ReferenceBinding)leafType, null, convertedEnclosing);
-// if (dimension > 0)
-// type = createArrayType(type, dimension);
-// }
-// return type;
-
public ArrayBinding createArrayType(TypeBinding type, int dimension) {
if (type.isValidBinding())
return environment().createArrayType(type, dimension);
@@ -561,19 +509,9 @@
return new ArrayBinding(type, dimension, environment());
}
- public ParameterizedTypeBinding createParameterizedType(ReferenceBinding genericType, TypeBinding[] arguments, ReferenceBinding enclosingType) {
- valid: {
- if (!genericType.isValidBinding()) break valid;
- for (int i = 0, max = arguments == null ? 0 : arguments.length; i < max; i++)
- if (!arguments[i].isValidBinding()) break valid;
- return environment().createParameterizedType(genericType, arguments, enclosingType);
- }
- return new ParameterizedTypeBinding(genericType, arguments, enclosingType, environment());
- }
-
public TypeVariableBinding[] createTypeVariables(TypeParameter[] typeParameters, Binding declaringElement) {
// do not construct type variables if source < 1.5
- if (typeParameters == null || environment().options.sourceLevel < ClassFileConstants.JDK1_5)
+ if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5)
return NoTypeVariables;
TypeVariableBinding[] typeVariableBindings = NoTypeVariables;
@@ -633,6 +571,25 @@
return null; // may answer null if no method around
}
+ /**
+ * Returns the immediately enclosing reference context, starting from current scope parent.
+ * If starting on a class, it will skip current class. If starting on unitScope, returns null.
+ */
+ public ReferenceContext enclosingReferenceContext() {
+ Scope current = this;
+ while ((current = current.parent) != null) {
+ switch(current.kind) {
+ case METHOD_SCOPE :
+ return ((MethodScope) current).referenceContext;
+ case CLASS_SCOPE :
+ return ((ClassScope) current).referenceContext;
+ case COMPILATION_UNIT_SCOPE :
+ return ((CompilationUnitScope) current).referenceContext;
+ }
+ }
+ return null;
+ }
+
/* Answer the receiver's enclosing source type.
*/
public final SourceTypeBinding enclosingSourceType() {
@@ -712,7 +669,7 @@
return (MethodBinding) found.elementAt(0); // no good match so just use the first one found
}
// no need to check for visibility - interface methods are public
- boolean isCompliant14 = unitScope.environment.options.complianceLevel >= ClassFileConstants.JDK1_4;
+ boolean isCompliant14 = compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
if (isCompliant14)
return mostSpecificMethodBinding(candidates, candidatesCount, argumentTypes, invocationSite);
return mostSpecificInterfaceMethodBinding(candidates, candidatesCount, invocationSite);
@@ -748,7 +705,7 @@
CompilationUnitScope unitScope = compilationUnitScope();
unitScope.recordTypeReferences(argumentTypes);
MethodBinding exactMethod = receiverType.getExactMethod(selector, argumentTypes, unitScope);
- if (exactMethod != null) {
+ if (exactMethod != null && exactMethod.typeVariables == NoTypeVariables) {
unitScope.recordTypeReferences(exactMethod.thrownExceptions);
// special treatment for Object.getClass() in 1.5 mode (substitute parameterized return type)
if (receiverType.isInterface() || exactMethod.canBeSeenBy(receiverType, invocationSite, this)) {
@@ -940,6 +897,8 @@
while (keepLooking) {
ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
if (itsInterfaces == null) { // needed for statically imported types which don't know their hierarchy yet
+ if (currentType.isHierarchyBeingConnected())
+ return null; // looking for an undefined member type in its own superclass ref
((SourceTypeBinding) currentType).scope.connectTypeHierarchy();
itsInterfaces = currentType.superInterfaces();
}
@@ -963,7 +922,7 @@
if (visibleMemberType == null)
visibleMemberType = memberType;
else
- return new ProblemReferenceBinding(typeName, Ambiguous);
+ return new ProblemReferenceBinding(typeName, null, Ambiguous);
} else {
notVisible = memberType;
}
@@ -985,7 +944,7 @@
if (visibleMemberType == null) {
visibleMemberType = memberType;
} else {
- ambiguous = new ProblemReferenceBinding(typeName, Ambiguous);
+ ambiguous = new ProblemReferenceBinding(typeName, null, Ambiguous);
break done;
}
} else {
@@ -1043,7 +1002,7 @@
currentType = getJavaLangObject();
}
- boolean isCompliant14 = unitScope.environment.options.complianceLevel >= ClassFileConstants.JDK1_4;
+ boolean isCompliant14 = compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
// superclass lookup
ReferenceBinding classHierarchyStart = currentType;
boolean mustBePublic = receiverType.isInterface();
@@ -1053,7 +1012,7 @@
int currentLength = currentMethods.length;
if (isCompliant14 && (mustBePublic || matchingMethod != null || found.size > 0)) {
- nextMethod: for (int i = 0; i < currentLength; i++) {
+ nextMethod: for (int i = 0, l = currentLength; i < l; i++) { // currentLength can be modified inside the loop
MethodBinding currentMethod = currentMethods[i];
if (mustBePublic && !currentMethod.isPublic()) { // only public methods from Object are visible to interface receiverTypes
currentLength--;
@@ -1068,6 +1027,8 @@
// BUT we can also ignore any overridden method since we already know the better match (fixes 80028)
if (matchingMethod != null) {
if (currentMethod.areParametersEqual(matchingMethod)) {
+ if (matchingMethod.typeVariables != NoTypeVariables && invocationSite.genericTypeArguments() == null)
+ continue nextMethod; // keep inherited substituted methods to detect anonymous errors
if (matchingMethod.hasSubstitutedParameters() && !currentMethod.original().areParametersEqual(matchingMethod.original()))
continue nextMethod; // keep inherited substituted methods to detect anonymous errors
currentLength--;
@@ -1200,7 +1161,7 @@
}
// check for duplicate parameterized methods
- if (unitScope.environment.options.sourceLevel >= ClassFileConstants.JDK1_5) {
+ if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
for (int i = 0; i < candidatesCount; i++) {
MethodBinding current = candidates[i];
if (current instanceof ParameterizedGenericMethodBinding)
@@ -1272,7 +1233,7 @@
case 'c':
if (CharOperation.equals(selector, CLONE)) {
return new UpdatedMethodBinding(
- environment().options.targetJDK >= ClassFileConstants.JDK1_4 ? (TypeBinding)receiverType : (TypeBinding)object, // remember its array type for codegen purpose on target>=1.4.0
+ compilerOptions().targetJDK >= ClassFileConstants.JDK1_4 ? (TypeBinding)receiverType : (TypeBinding)object, // remember its array type for codegen purpose on target>=1.4.0
(methodBinding.modifiers & ~AccProtected) | AccPublic,
CLONE,
methodBinding.returnType,
@@ -1493,7 +1454,7 @@
NonStaticReferenceInStaticContext);
}
}
- if (enclosingType == fieldBinding.declaringClass || environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
+ if (enclosingType == fieldBinding.declaringClass || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
// found a valid field in the 'immediate' scope (ie. not inherited)
// OR in 1.4 mode (inherited shadows enclosing)
if (foundField == null) {
@@ -1532,8 +1493,7 @@
// in order to do so, we change the flag as we exit from the type, not the method
// itself, because the class scope is used to retrieve the fields.
MethodScope enclosingMethodScope = scope.methodScope();
- insideConstructorCall =
- enclosingMethodScope == null ? false : enclosingMethodScope.isConstructorCall;
+ insideConstructorCall = enclosingMethodScope == null ? false : enclosingMethodScope.isConstructorCall;
break;
case COMPILATION_UNIT_SCOPE :
break done;
@@ -1555,7 +1515,7 @@
foundField = null;
}
- if (environment().options.sourceLevel >= ClassFileConstants.JDK1_5) {
+ if (compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
// at this point the scope is a compilation unit scope & need to check for imported static fields
CompilationUnitScope unitScope = (CompilationUnitScope) scope;
ImportBinding[] imports = unitScope.imports;
@@ -1596,7 +1556,7 @@
if (importReference != null) importReference.used = true;
if (foundInImport)
// Answer error binding -- import on demand conflict; name found in two import on demand packages.
- return new ProblemReferenceBinding(name, Ambiguous);
+ return new ProblemReferenceBinding(name, null, Ambiguous);
foundField = temp;
foundInImport = true;
}
@@ -1852,7 +1812,7 @@
if (receiverType == methodBinding.declaringClass
|| (receiverType.getMethods(selector)) != NoMethods
- || ((fuzzyProblem == null || fuzzyProblem.problemId() != NotVisible) && environment().options.complianceLevel >= ClassFileConstants.JDK1_4)) {
+ || ((fuzzyProblem == null || fuzzyProblem.problemId() != NotVisible) && compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)) {
// found a valid method in the 'immediate' scope (ie. not inherited)
// OR the receiverType implemented a method with the correct name
// OR in 1.4 mode (inherited visible shadows enclosing)
@@ -1917,18 +1877,23 @@
if (foundMethod != null)
return foundMethod;
- if (insideStaticContext && environment().options.sourceLevel >= ClassFileConstants.JDK1_5) {
+ if (insideStaticContext && compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
// at this point the scope is a compilation unit scope & need to check for imported static methods
CompilationUnitScope unitScope = (CompilationUnitScope) scope;
ImportBinding[] imports = unitScope.imports;
if (imports != null) {
- int importLevel = -1; // -1 = not found, 0 = on demand match, 1 = single import match
+ MethodBinding[] visible = null;
+ boolean skipOnDemand = false; // set to true when matched static import of method name so stop looking for on demand methods
for (int i = 0, length = imports.length; i < length; i++) {
ImportBinding importBinding = imports[i];
if (importBinding.isStatic()) {
Binding resolvedImport = importBinding.resolvedImport;
MethodBinding possible = null;
- if (!importBinding.onDemand && importBinding.isStatic()) {
+ if (importBinding.onDemand) {
+ if (!skipOnDemand && resolvedImport instanceof ReferenceBinding)
+ // answers closest approximation, may not check argumentTypes or visibility
+ possible = findMethod((ReferenceBinding) resolvedImport, selector, argumentTypes, invocationSite);
+ } else {
if (resolvedImport instanceof MethodBinding) {
MethodBinding staticMethod = (MethodBinding) resolvedImport;
if (CharOperation.equals(staticMethod.selector, selector))
@@ -1946,9 +1911,6 @@
possible = findMethod((ReferenceBinding) referencedType, selector, argumentTypes, invocationSite);
}
}
- } else if (importBinding.onDemand && importLevel < 1 && resolvedImport instanceof ReferenceBinding) {
- // answers closest approximation, may not check argumentTypes or visibility
- possible = findMethod((ReferenceBinding) resolvedImport, selector, argumentTypes, invocationSite);
}
if (possible != null && possible != foundMethod) {
if (!possible.isValidBinding()) {
@@ -1961,21 +1923,25 @@
if (compatibleMethod.canBeSeenBy(unitScope.fPackage)) {
ImportReference importReference = importBinding.reference;
if (importReference != null) importReference.used = true;
- int matchingImportLevel = importBinding.onDemand ? 0 : 1;
- if (matchingImportLevel == importLevel) {
- scope = this;
- while (true) {
- switch (scope.kind) {
- case CLASS_SCOPE :
- return new ProblemMethodBinding(selector, argumentTypes, ((ClassScope) scope).referenceContext.binding, Ambiguous);
- case COMPILATION_UNIT_SCOPE :
- return new ProblemMethodBinding(compatibleMethod, selector, compatibleMethod.parameters, Ambiguous);
- }
- scope = scope.parent;
+ if (foundMethod == null || !foundMethod.isValidBinding()) {
+ foundMethod = compatibleMethod;
+ if (!importBinding.onDemand && foundMethod.isValidBinding())
+ skipOnDemand = true;
+ } else {
+ if (!skipOnDemand && !importBinding.onDemand) {
+ visible = null; // forget previous matches from on demand imports
+ foundMethod = compatibleMethod;
+ skipOnDemand = true;
+ } else if (visible == null) {
+ visible = new MethodBinding[] {foundMethod, compatibleMethod};
+ } else {
+ int visibleLength = visible.length;
+ MethodBinding[] temp = new MethodBinding[visibleLength + 1];
+ System.arraycopy(visible, 0, temp, 0, visibleLength);
+ temp[visibleLength] = compatibleMethod;
+ visible = temp;
}
}
- foundMethod = compatibleMethod;
- importLevel = matchingImportLevel;
} else if (foundMethod == null) {
foundMethod = new ProblemMethodBinding(compatibleMethod, selector, compatibleMethod.parameters, NotVisible);
}
@@ -1987,6 +1953,8 @@
}
}
}
+ if (visible != null)
+ foundMethod = mostSpecificMethodBinding(visible, visible.length, argumentTypes, invocationSite);
}
if (foundMethod != null) {
invocationSite.setActualReceiverType(foundMethod.declaringClass);
@@ -2047,14 +2015,7 @@
problemReporter().isClassPathCorrect(JAVA_LANG_ENUM, referenceCompilationUnit());
return null; // will not get here since the above error aborts the compilation
}
- public final ReferenceBinding getJavaLangError() {
- compilationUnitScope().recordQualifiedReference(JAVA_LANG_ERROR);
- ReferenceBinding type = environment().getType(JAVA_LANG_ERROR);
- if (type != null) return type;
-
- problemReporter().isClassPathCorrect(JAVA_LANG_ERROR, referenceCompilationUnit());
- return null; // will not get here since the above error aborts the compilation
- }
+
public final ReferenceBinding getJavaLangIterable() {
compilationUnitScope().recordQualifiedReference(JAVA_LANG_ITERABLE);
ReferenceBinding type = environment().getType(JAVA_LANG_ITERABLE);
@@ -2072,15 +2033,6 @@
return null; // will not get here since the above error aborts the compilation
}
- public final ReferenceBinding getJavaLangRuntimeException() {
- compilationUnitScope().recordQualifiedReference(JAVA_LANG_RUNTIMEEXCEPTION);
- ReferenceBinding type = environment().getType(JAVA_LANG_RUNTIMEEXCEPTION);
- if (type != null) return type;
-
- problemReporter().isClassPathCorrect(JAVA_LANG_RUNTIMEEXCEPTION, referenceCompilationUnit());
- return null; // will not get here since the above error aborts the compilation
- }
-
public final ReferenceBinding getJavaLangString() {
compilationUnitScope().recordQualifiedReference(JAVA_LANG_STRING);
ReferenceBinding type = environment().getType(JAVA_LANG_STRING);
@@ -2112,7 +2064,7 @@
public final ReferenceBinding getMemberType(char[] typeName, ReferenceBinding enclosingType) {
ReferenceBinding memberType = findMemberType(typeName, enclosingType);
if (memberType != null) return memberType;
- return new ProblemReferenceBinding(typeName, NotFound);
+ return new ProblemReferenceBinding(typeName, null, NotFound);
}
public MethodBinding getMethod(TypeBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
@@ -2174,7 +2126,7 @@
compilationUnitScope().recordQualifiedReference(compoundName);
Binding binding = getTypeOrPackage(compoundName[0], Binding.TYPE | Binding.PACKAGE);
if (binding == null)
- return new ProblemReferenceBinding(compoundName[0], NotFound);
+ return new ProblemReferenceBinding(compoundName[0], null, NotFound);
if (!binding.isValidBinding())
return (ReferenceBinding) binding;
@@ -2187,16 +2139,18 @@
if (binding == null)
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null,
NotFound);
if (!binding.isValidBinding())
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
binding.problemId());
if (!(binding instanceof PackageBinding))
return packageBinding;
packageBinding = (PackageBinding) binding;
}
- return new ProblemReferenceBinding(compoundName, NotFound);
+ return new ProblemReferenceBinding(compoundName, null, NotFound);
}
/* Answer the type binding that corresponds the given name, starting the lookup in the receiver.
@@ -2224,10 +2178,12 @@
if (binding == null)
return new ProblemReferenceBinding(
CharOperation.arrayConcat(packageBinding.compoundName, name),
+ null,
NotFound);
if (!binding.isValidBinding())
return new ProblemReferenceBinding(
CharOperation.arrayConcat(packageBinding.compoundName, name),
+ null, // TODO should improve
binding.problemId());
ReferenceBinding typeBinding = (ReferenceBinding) binding;
@@ -2256,7 +2212,7 @@
Binding binding =
getTypeOrPackage(compoundName[0], typeNameLength == 1 ? Binding.TYPE : Binding.TYPE | Binding.PACKAGE);
if (binding == null)
- return new ProblemReferenceBinding(compoundName[0], NotFound);
+ return new ProblemReferenceBinding(compoundName[0], null, NotFound);
if (!binding.isValidBinding())
return (ReferenceBinding) binding;
@@ -2269,10 +2225,12 @@
if (binding == null)
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null,
NotFound);
if (!binding.isValidBinding())
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
binding.problemId());
if (!(binding instanceof PackageBinding))
break;
@@ -2281,6 +2239,7 @@
if (binding instanceof PackageBinding)
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null,
NotFound);
checkVisibility = true;
}
@@ -2302,11 +2261,12 @@
ProblemReferenceBinding problemBinding = (ProblemReferenceBinding) typeBinding;
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
- problemBinding.original,
+ problemBinding.closestMatch,
typeBinding.problemId());
}
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
typeBinding.problemId());
}
}
@@ -2340,30 +2300,30 @@
ReferenceBinding localType = ((BlockScope) scope).findLocalType(name); // looks in this scope only
if (localType != null) {
if (foundType != null && foundType != localType)
- return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName);
+ return new ProblemReferenceBinding(name, foundType, InheritedNameHidesEnclosingName);
return localType;
}
break;
case CLASS_SCOPE :
SourceTypeBinding sourceType = ((ClassScope) scope).referenceContext.binding;
- if (sourceType.isHierarchyBeingConnected()) {
- // type variables take precedence over the source type, ex. class X <X> extends X == class X <Y> extends Y
+ if (scope == this && sourceType.isHierarchyBeingConnected()) {
+ // type variables take precedence over the source type, ex. class X <X> extends X == class X <Y> extends Y
+ // but not when we step out to the enclosing type
TypeVariableBinding typeVariable = sourceType.getTypeVariable(name);
if (typeVariable != null)
return typeVariable;
if (CharOperation.equals(name, sourceType.sourceName))
return sourceType;
- insideStaticContext |= (sourceType.modifiers & AccStatic) != 0; // not isStatic()
+ insideStaticContext |= sourceType.isStatic();
break;
}
// type variables take precedence over member types
TypeVariableBinding typeVariable = sourceType.getTypeVariable(name);
if (typeVariable != null) {
if (insideStaticContext) // do not consider this type modifiers: access is legite within same type
- return new ProblemReferenceBinding(name, NonStaticReferenceInStaticContext);
+ return new ProblemReferenceBinding(name, typeVariable, NonStaticReferenceInStaticContext);
return typeVariable;
}
- insideStaticContext |= (sourceType.modifiers & AccStatic) != 0; // not isStatic()
if (!insideTypeAnnotation) {
// 6.5.5.1 - member types have precedence over top-level type in same unit
ReferenceBinding memberType = findMemberType(name, sourceType);
@@ -2373,20 +2333,20 @@
// supercedes any potential InheritedNameHidesEnclosingName problem
return memberType;
// make the user qualify the type, likely wants the first inherited type
- return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName);
+ return new ProblemReferenceBinding(name, foundType, InheritedNameHidesEnclosingName);
}
if (memberType.isValidBinding()) {
if (sourceType == memberType.enclosingType()
- || environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
+ || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
if (insideStaticContext && !memberType.isStatic() && sourceType.isGenericType())
- return new ProblemReferenceBinding(name, NonStaticReferenceInStaticContext);
+ return new ProblemReferenceBinding(name, memberType, NonStaticReferenceInStaticContext);
// found a valid type in the 'immediate' scope (ie. not inherited)
// OR in 1.4 mode (inherited shadows enclosing)
if (foundType == null)
return memberType;
// if a valid type was found, complain when another is found in an 'immediate' enclosing type (ie. not inherited)
if (foundType.isValidBinding() && foundType != memberType)
- return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName);
+ return new ProblemReferenceBinding(name, foundType, InheritedNameHidesEnclosingName);
}
}
if (foundType == null || (foundType.problemId() == NotVisible && memberType.problemId() != NotVisible))
@@ -2395,9 +2355,10 @@
}
}
insideTypeAnnotation = false;
+ insideStaticContext |= sourceType.isStatic();
if (CharOperation.equals(sourceType.sourceName, name)) {
if (foundType != null && foundType != sourceType && foundType.problemId() != NotVisible)
- return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName);
+ return new ProblemReferenceBinding(name, foundType, InheritedNameHidesEnclosingName);
return sourceType;
}
break;
@@ -2412,43 +2373,63 @@
// at this point the scope is a compilation unit scope
CompilationUnitScope unitScope = (CompilationUnitScope) scope;
- PackageBinding currentPackage = unitScope.fPackage;
+ HashtableOfObject typeOrPackageCache = unitScope.typeOrPackageCache;
+ if (typeOrPackageCache != null) {
+ Binding binding = (Binding) typeOrPackageCache.get(name);
+ if (binding != null) { // can also include NotFound ProblemReferenceBindings if we already know this name is not found
+ if (binding instanceof ImportBinding) { // single type import cached in faultInImports(), replace it in the cache with the type
+ ImportReference importReference = ((ImportBinding) binding).reference;
+ if (importReference != null) importReference.used = true;
+ if (binding instanceof ImportConflictBinding)
+ typeOrPackageCache.put(name, binding = ((ImportConflictBinding) binding).conflictingTypeBinding); // already know its visible
+ else
+ typeOrPackageCache.put(name, binding = ((ImportBinding) binding).resolvedImport); // already know its visible
+ }
+ if ((mask & Binding.TYPE) != 0) {
+ if (foundType != null && foundType.problemId() != NotVisible && binding.problemId() != Ambiguous)
+ return foundType; // problem type from above supercedes NotFound type but not Ambiguous import case
+ if (binding instanceof ReferenceBinding)
+ return binding; // cached type found in previous walk below
+ }
+ if ((mask & Binding.PACKAGE) != 0 && binding instanceof PackageBinding)
+ return binding; // cached package found in previous walk below
+ }
+ }
+
// ask for the imports + name
if ((mask & Binding.TYPE) != 0) {
- // check single type imports.
-
ImportBinding[] imports = unitScope.imports;
- if (imports != null) {
- HashtableOfObject typeImports = unitScope.resolvedSingeTypeImports;
- if (typeImports != null) {
- ImportBinding typeImport = (ImportBinding) typeImports.get(name);
- if (typeImport != null) {
- ImportReference importReference = typeImport.reference;
- if (importReference != null) importReference.used = true;
- return typeImport.resolvedImport; // already know its visible
- }
- } else {
- // walk all the imports since resolvedSingleTypeImports is not yet initialized
- for (int i = 0, length = imports.length; i < length; i++) {
- ImportBinding typeImport = imports[i];
- if (!typeImport.onDemand) {
- if (CharOperation.equals(typeImport.compoundName[typeImport.compoundName.length - 1], name)) {
- Binding resolvedImport = unitScope.resolveSingleImport(typeImport);
- if (resolvedImport != null && resolvedImport instanceof TypeBinding) {
- ImportReference importReference = typeImport.reference;
- if (importReference != null)
- importReference.used = true;
- return resolvedImport; // already know its visible
- }
+ if (imports != null && typeOrPackageCache == null) { // walk single type imports since faultInImports() has not run yet
+ nextImport : for (int i = 0, length = imports.length; i < length; i++) {
+ ImportBinding importBinding = imports[i];
+ if (!importBinding.onDemand) {
+ if (CharOperation.equals(importBinding.compoundName[importBinding.compoundName.length - 1], name)) {
+ Binding resolvedImport = unitScope.resolveSingleImport(importBinding);
+ if (resolvedImport == null) continue nextImport;
+ if (resolvedImport instanceof MethodBinding) {
+ resolvedImport = (ReferenceBinding) getType(importBinding.compoundName, importBinding.compoundName.length);
+ if (!resolvedImport.isValidBinding()) continue nextImport;
+ }
+ if (resolvedImport instanceof TypeBinding) {
+ ImportReference importReference = importBinding.reference;
+ if (importReference != null)
+ importReference.used = true;
+ return resolvedImport; // already know its visible
}
}
}
}
}
+
// check if the name is in the current package, skip it if its a sub-package
+ PackageBinding currentPackage = unitScope.fPackage;
unitScope.recordReference(currentPackage.compoundName, name);
Binding binding = currentPackage.getTypeOrPackage(name);
- if (binding instanceof ReferenceBinding) return binding; // type is always visible to its own package
+ if (binding instanceof ReferenceBinding) {
+ if (typeOrPackageCache != null)
+ typeOrPackageCache.put(name, binding);
+ return binding; // type is always visible to its own package
+ }
// check on demand imports
if (imports != null) {
@@ -2458,18 +2439,27 @@
ImportBinding someImport = imports[i];
if (someImport.onDemand) {
Binding resolvedImport = someImport.resolvedImport;
- ReferenceBinding temp = resolvedImport instanceof PackageBinding
- ? findType(name, (PackageBinding) resolvedImport, currentPackage)
- : (someImport.isStatic()
- ? findMemberType(name, (ReferenceBinding) resolvedImport) // static imports are allowed to see inherited member types
- : findDirectMemberType(name, (ReferenceBinding) resolvedImport));
- if (temp != null) {
+ ReferenceBinding temp = null;
+ if (resolvedImport instanceof PackageBinding) {
+ temp = findType(name, (PackageBinding) resolvedImport, currentPackage);
+ } else if (someImport.isStatic()) {
+ temp = findMemberType(name, (ReferenceBinding) resolvedImport); // static imports are allowed to see inherited member types
+ if (temp != null && !temp.isStatic())
+ temp = null;
+ } else {
+ temp = findDirectMemberType(name, (ReferenceBinding) resolvedImport);
+ }
+ if (temp != type && temp != null) {
if (temp.isValidBinding()) {
ImportReference importReference = someImport.reference;
if (importReference != null) importReference.used = true;
- if (foundInImport)
+ if (foundInImport) {
// Answer error binding -- import on demand conflict; name found in two import on demand packages.
- return new ProblemReferenceBinding(name, Ambiguous);
+ temp = new ProblemReferenceBinding(name, null, Ambiguous);
+ if (typeOrPackageCache != null)
+ typeOrPackageCache.put(name, temp);
+ return temp;
+ }
type = temp;
foundInImport = true;
} else if (foundType == null) {
@@ -2478,19 +2468,31 @@
}
}
}
- if (type != null) return type;
+ if (type != null) {
+ if (typeOrPackageCache != null)
+ typeOrPackageCache.put(name, type);
+ return type;
+ }
}
}
unitScope.recordSimpleReference(name);
if ((mask & Binding.PACKAGE) != 0) {
PackageBinding packageBinding = unitScope.environment.getTopLevelPackage(name);
- if (packageBinding != null) return packageBinding;
+ if (packageBinding != null) {
+ if (typeOrPackageCache != null)
+ typeOrPackageCache.put(name, packageBinding);
+ return packageBinding;
+ }
}
// Answer error binding -- could not find name
- if (foundType != null) return foundType; // problem type from above
- return new ProblemReferenceBinding(name, NotFound);
+ if (foundType == null) {
+ foundType = new ProblemReferenceBinding(name, null, NotFound);
+ if (typeOrPackageCache != null && (mask & Binding.PACKAGE) != 0) // only put NotFound type in cache if you know its not a package
+ typeOrPackageCache.put(name, foundType);
+ }
+ return foundType;
}
// Added for code assist... NOT Public API
@@ -2516,10 +2518,12 @@
if (binding == null)
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null,
NotFound);
if (!binding.isValidBinding())
return new ProblemReferenceBinding(
CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
binding.problemId());
if (!(binding instanceof PackageBinding))
break;
@@ -2529,16 +2533,8 @@
checkVisibility = true;
}
// binding is now a ReferenceBinding
- ReferenceBinding qualifiedType = null;
-
ReferenceBinding typeBinding = (ReferenceBinding) binding;
- if (typeBinding.isGenericType()) {
- qualifiedType = this.environment().createRawType(typeBinding, qualifiedType);
- } else {
- qualifiedType = (qualifiedType != null && (qualifiedType.isRawType() || qualifiedType.isParameterizedType()))
- ? this.createParameterizedType(typeBinding, null, qualifiedType)
- : typeBinding;
- }
+ ReferenceBinding qualifiedType = (ReferenceBinding) this.environment().convertToRawType(typeBinding);
if (checkVisibility) // handles the fall through case
if (!typeBinding.canBeSeenBy(this))
@@ -2549,20 +2545,20 @@
while (currentIndex < nameLength) {
typeBinding = getMemberType(compoundName[currentIndex++], typeBinding);
-
+ // checks visibility
+ if (!typeBinding.isValidBinding())
+ return new ProblemReferenceBinding(
+ CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
+ typeBinding.problemId());
+
if (typeBinding.isGenericType()) {
qualifiedType = this.environment().createRawType(typeBinding, qualifiedType);
} else {
qualifiedType = (qualifiedType != null && (qualifiedType.isRawType() || qualifiedType.isParameterizedType()))
- ? this.createParameterizedType(typeBinding, null, qualifiedType)
+ ? this.environment().createParameterizedType(typeBinding, null, qualifiedType)
: typeBinding;
}
-
- // checks visibility
- if (!qualifiedType.isValidBinding())
- return new ProblemReferenceBinding(
- CharOperation.subarray(compoundName, 0, currentIndex),
- qualifiedType.problemId());
}
return qualifiedType;
}
@@ -2636,6 +2632,7 @@
}
return trimmedResult;
}
+
/**
* Returns the immediately enclosing switchCase statement (carried by closest blockScope),
*/
@@ -2649,8 +2646,14 @@
return null;
}
- public boolean isBoxingCompatibleWith(TypeBinding left, TypeBinding right) {
- return left.isBaseType() != right.isBaseType() && environment().isBoxingCompatibleWith(left, right);
+ public boolean isBoxingCompatibleWith(TypeBinding expressionType, TypeBinding targetType) {
+ LookupEnvironment environment = environment();
+ if (environment.globalOptions.sourceLevel < ClassFileConstants.JDK1_5 || expressionType.isBaseType() == targetType.isBaseType())
+ return false;
+
+ // check if autoboxed type is compatible
+ TypeBinding convertedType = environment.computeBoxingType(expressionType);
+ return convertedType == targetType || convertedType.isCompatibleWith(targetType);
}
/* Answer true if the scope is nested inside a given field declaration.
@@ -2769,32 +2772,41 @@
int length = invocations.size();
Iterator iter = invocations.iterator();
if (length == 1) return (TypeBinding) iter.next();
+
+ // if mec is an array type, intersect invocation leaf component types, then promote back to array
+ int dim = mec.dimensions();
+ mec = mec.leafComponentType();
+
int argLength = mec.typeVariables().length;
if (argLength == 0) return mec; // should be caught by no invocation check
// infer proper parameterized type from invocations
TypeBinding[] bestArguments = new TypeBinding[argLength];
while (iter.hasNext()) {
- TypeBinding invocation = (TypeBinding)iter.next();
- TypeVariableBinding[] invocationVariables = invocation.typeVariables();
- if (invocation.isGenericType()) {
- for (int i = 0; i < argLength; i++) {
- TypeBinding bestArgument = leastContainingTypeArgument(bestArguments[i], invocationVariables[i], (ReferenceBinding) mec, i, lubStack);
- if (bestArgument == null) return null;
- bestArguments[i] = bestArgument;
- }
- } else if (invocation.isParameterizedType()) {
- ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding)invocation;
- for (int i = 0; i < argLength; i++) {
- TypeBinding bestArgument = leastContainingTypeArgument(bestArguments[i], parameterizedType.arguments[i], (ReferenceBinding) mec, i, lubStack);
- if (bestArgument == null) return null;
- bestArguments[i] = bestArgument;
- }
- } else if (invocation.isRawType()) {
- return invocation; // raw type is taking precedence
+ TypeBinding invocation = ((TypeBinding)iter.next()).leafComponentType();
+ switch (invocation.kind()) {
+ case Binding.GENERIC_TYPE :
+ TypeVariableBinding[] invocationVariables = invocation.typeVariables();
+ for (int i = 0; i < argLength; i++) {
+ TypeBinding bestArgument = leastContainingTypeArgument(bestArguments[i], invocationVariables[i], (ReferenceBinding) mec, i, lubStack);
+ if (bestArgument == null) return null;
+ bestArguments[i] = bestArgument;
+ }
+ break;
+ case Binding.PARAMETERIZED_TYPE :
+ ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding)invocation;
+ for (int i = 0; i < argLength; i++) {
+ TypeBinding bestArgument = leastContainingTypeArgument(bestArguments[i], parameterizedType.arguments[i], (ReferenceBinding) mec, i, lubStack);
+ if (bestArgument == null) return null;
+ bestArguments[i] = bestArgument;
+ }
+ break;
+ case Binding.RAW_TYPE :
+ return dim == 0 ? invocation : environment().createArrayType(invocation, dim); // raw type is taking precedence
}
}
- return createParameterizedType((ReferenceBinding) mec.erasure(), bestArguments, null);
+ TypeBinding least = environment().createParameterizedType((ReferenceBinding) mec.erasure(), bestArguments, mec.enclosingType());
+ return dim == 0 ? least : environment().createArrayType(least, dim);
}
// JLS 15.12.2
@@ -2874,7 +2886,16 @@
}
// 15.12.2
+ /**
+ * Returns VoidBinding if types have no intersection (e.g. 2 unrelated interfaces), or null if
+ * no common supertype (e.g. List<String> and List<Exception>), or the intersection type if possible
+ */
public TypeBinding lowerUpperBound(TypeBinding[] types) {
+ int typeLength = types.length;
+ if (typeLength == 1) {
+ TypeBinding type = types[0];
+ return type == null ? VoidBinding : type;
+ }
return lowerUpperBound(types, new ArrayList(1));
}
@@ -2895,7 +2916,7 @@
nextTypeCheck: for (int j = 0; j < typeLength; j++) {
TypeBinding type = types[j];
for (int k = 0; k < lubTypeLength; k++) {
- if (lubTypes[k] == type) continue nextTypeCheck; // type found, jump to next one
+ if (lubTypes[k] == type || lubTypes[k].isEquivalentTo(type)) continue nextTypeCheck; // type found, jump to next one
}
continue nextLubCheck; // type not found in current lubTypes
}
@@ -2911,31 +2932,38 @@
if (length == 0) return VoidBinding;
int count = 0;
TypeBinding firstBound = null;
+ int commonDim = -1;
for (int i = 0; i < length; i++) {
TypeBinding mec = mecs[i];
if (mec == null) continue;
mec = leastContainingInvocation(mec, (Set)invocations.get(mec), lubStack);
if (mec == null) return null;
- if (!mec.isInterface()) firstBound = mec;
+ int dim = mec.dimensions();
+ if (commonDim == -1) {
+ commonDim = dim;
+ } else if (dim != commonDim) { // not all types have same dimension
+ return null;
+ }
+ if (firstBound == null && !mec.leafComponentType().isInterface()) firstBound = mec.leafComponentType();
mecs[count++] = mec; // recompact them to the front
-
}
switch (count) {
case 0 : return VoidBinding;
case 1 : return mecs[0];
case 2 :
- if (mecs[1].id == T_JavaLangObject) return mecs[0];
- if (mecs[0].id == T_JavaLangObject) return mecs[1];
+ if ((commonDim == 0 ? mecs[1].id : mecs[1].leafComponentType().id) == T_JavaLangObject) return mecs[0];
+ if ((commonDim == 0 ? mecs[0].id : mecs[0].leafComponentType().id) == T_JavaLangObject) return mecs[1];
}
TypeBinding[] otherBounds = new TypeBinding[count - 1];
int rank = 0;
for (int i = 0; i < count; i++) {
- TypeBinding mec = mecs[i];
+ TypeBinding mec = commonDim == 0 ? mecs[i] : mecs[i].leafComponentType();
if (mec.isInterface()) {
otherBounds[rank++] = (ReferenceBinding)mec;
}
}
- return environment().createWildcard(null, 0, firstBound, otherBounds, Wildcard.EXTENDS);
+ TypeBinding intersectionType = environment().createWildcard(null, 0, firstBound, otherBounds, Wildcard.EXTENDS);
+ return commonDim == 0 ? intersectionType : environment().createArrayType(intersectionType, commonDim);
}
public final MethodScope methodScope() {
@@ -2956,7 +2984,7 @@
* of minimal erased types, where some nulls may appear (and must simply be
* ignored).
*/
- private TypeBinding[] minimalErasedCandidates(TypeBinding[] types, Map allInvocations) {
+ protected TypeBinding[] minimalErasedCandidates(TypeBinding[] types, Map allInvocations) {
int length = types.length;
int indexOfFirst = -1, actualLength = 0;
for (int i = 0; i < length; i++) {
@@ -2970,80 +2998,125 @@
case 0: return NoTypes;
case 1: return types;
}
+ TypeBinding firstType = types[indexOfFirst];
+ if (firstType.isBaseType()) return null;
// record all supertypes of type
// intersect with all supertypes of otherType
- TypeBinding firstType = types[indexOfFirst];
- TypeBinding[] superTypes;
- int superLength;
- if (firstType.isBaseType()) {
- return null;
- } else if (firstType.isArrayType()) {
- superLength = 4;
- if (firstType.erasure() != firstType) {
- ArrayList someInvocations = new ArrayList(1);
- someInvocations.add(firstType);
- allInvocations.put(firstType.erasure(), someInvocations);
- }
- superTypes = new TypeBinding[] { // inject well-known array supertypes
- firstType.erasure(),
- getJavaIoSerializable(),
- getJavaLangCloneable(),
- getJavaLangObject(),
- };
- } else {
- ArrayList typesToVisit = new ArrayList(5);
- TypeBinding firstErasure = firstType.erasure();
- if (firstErasure != firstType) {
- Set someInvocations = new HashSet(1);
- someInvocations.add(firstType);
- allInvocations.put(firstErasure, someInvocations);
- }
- typesToVisit.add(firstErasure);
- int max = 1;
- if (firstErasure.isArrayType()) {
- typesToVisit.add(getJavaIoSerializable());
- typesToVisit.add(getJavaLangCloneable());
- typesToVisit.add(getJavaLangObject());
- max += 3;
- }
- ReferenceBinding currentType = (ReferenceBinding)firstType;
- for (int i = 0; i < max; i++) {
- TypeBinding typeToVisit = (TypeBinding) typesToVisit.get(i);
- if (typeToVisit.isArrayType()) continue;
- currentType = (ReferenceBinding) typeToVisit;
- // inject super interfaces prior to superclass
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- for (int j = 0, count = itsInterfaces.length; j < count; j++) {
- TypeBinding itsInterface = itsInterfaces[j];
- TypeBinding itsInterfaceErasure = itsInterface.erasure();
- if (!typesToVisit.contains(itsInterfaceErasure)) {
- if (itsInterfaceErasure != itsInterface) {
- Set someInvocations = new HashSet(1);
- someInvocations.add(itsInterface);
- allInvocations.put(itsInterfaceErasure, someInvocations);
- }
- typesToVisit.add(itsInterfaceErasure);
- max++;
- }
- }
- TypeBinding itsSuperclass = currentType.superclass();
- if (itsSuperclass != null) {
- TypeBinding itsSuperclassErasure = itsSuperclass.erasure();
- if (!typesToVisit.contains(itsSuperclassErasure)) {
- if (itsSuperclassErasure != itsSuperclass) {
- Set someInvocations = new HashSet(1);
- someInvocations.add(itsSuperclass);
- allInvocations.put(itsSuperclassErasure, someInvocations);
+ ArrayList typesToVisit = new ArrayList(5);
+
+ int dim = firstType.dimensions();
+ TypeBinding leafType = firstType.leafComponentType();
+ TypeBinding firstErasure = (leafType.isTypeVariable() || leafType.isWildcard()/*&& !leafType.isCapture()*/) ? firstType : firstType.erasure();
+ if (firstErasure != firstType) {
+ Set someInvocations = new HashSet(1);
+ someInvocations.add(firstType);
+ allInvocations.put(firstErasure, someInvocations);
+ }
+ typesToVisit.add(firstType);
+ int max = 1;
+ ReferenceBinding currentType;
+ for (int i = 0; i < max; i++) {
+ TypeBinding typeToVisit = (TypeBinding) typesToVisit.get(i);
+ dim = typeToVisit.dimensions();
+ if (dim > 0) {
+ leafType = typeToVisit.leafComponentType();
+ switch(leafType.id) {
+ case T_JavaLangObject:
+ if (dim > 1) { // Object[][] supertype is Object[]
+ TypeBinding elementType = ((ArrayBinding)typeToVisit).elementsType();
+ if (!typesToVisit.contains(elementType)) {
+ typesToVisit.add(elementType);
+ max++;
+ }
+ continue;
}
- typesToVisit.add(itsSuperclassErasure);
+ // fallthrough
+ case T_byte:
+ case T_short:
+ case T_char:
+ case T_boolean:
+ case T_int:
+ case T_long:
+ case T_float:
+ case T_double:
+ TypeBinding superType = getJavaIoSerializable();
+ if (!typesToVisit.contains(superType)) {
+ typesToVisit.add(superType);
+ max++;
+ }
+ superType = getJavaLangCloneable();
+ if (!typesToVisit.contains(superType)) {
+ typesToVisit.add(superType);
+ max++;
+ }
+ superType = getJavaLangObject();
+ if (!typesToVisit.contains(superType)) {
+ typesToVisit.add(superType);
+ max++;
+ }
+ continue;
+
+ default:
+ }
+ typeToVisit = leafType;
+ }
+ currentType = (ReferenceBinding) typeToVisit;
+ if (currentType.isCapture()) {
+ TypeBinding firstBound = ((CaptureBinding) currentType).firstBound;
+ if (firstBound != null && firstBound.isArrayType()) {
+ TypeBinding superType = dim == 0 ? firstBound : (TypeBinding)environment().createArrayType(firstBound, dim); // recreate array if needed
+ if (!typesToVisit.contains(superType)) {
+ typesToVisit.add(superType);
max++;
+ TypeBinding superTypeErasure = (firstBound.isTypeVariable() || firstBound.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure();
+ if (superTypeErasure != superType) {
+ Set someInvocations = new HashSet(1);
+ someInvocations.add(superType);
+ allInvocations.put(superTypeErasure, someInvocations);
+ }
+ }
+ continue;
+ }
+ }
+ // inject super interfaces prior to superclass
+ ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+ for (int j = 0, count = itsInterfaces.length; j < count; j++) {
+ TypeBinding itsInterface = itsInterfaces[j];
+ TypeBinding superType = dim == 0 ? itsInterface : (TypeBinding)environment().createArrayType(itsInterface, dim); // recreate array if needed
+ if (!typesToVisit.contains(superType)) {
+ typesToVisit.add(superType);
+ max++;
+ TypeBinding superTypeErasure = (itsInterface.isTypeVariable() || itsInterface.isWildcard() /*&& !itsInterface.isCapture()*/) ? superType : superType.erasure();
+ if (superTypeErasure != superType) {
+ Set someInvocations = new HashSet(1);
+ someInvocations.add(superType);
+ allInvocations.put(superTypeErasure, someInvocations);
+ }
+ }
+ }
+ TypeBinding itsSuperclass = currentType.superclass();
+ if (itsSuperclass != null) {
+ TypeBinding superType = dim == 0 ? itsSuperclass : (TypeBinding)environment().createArrayType(itsSuperclass, dim); // recreate array if needed
+ if (!typesToVisit.contains(superType)) {
+ typesToVisit.add(superType);
+ max++;
+ TypeBinding superTypeErasure = (itsSuperclass.isTypeVariable() || itsSuperclass.isWildcard() /*&& !itsSuperclass.isCapture()*/) ? superType : superType.erasure();
+ if (superTypeErasure != superType) {
+ Set someInvocations = new HashSet(1);
+ someInvocations.add(superType);
+ allInvocations.put(superTypeErasure, someInvocations);
}
}
}
- superLength = typesToVisit.size();
- superTypes = new TypeBinding[superLength];
- typesToVisit.toArray(superTypes);
+ }
+ int superLength = typesToVisit.size();
+ TypeBinding[] erasedSuperTypes = new TypeBinding[superLength];
+ int rank = 0;
+ for (Iterator iter = typesToVisit.iterator(); iter.hasNext();) {
+ TypeBinding type = (TypeBinding)iter.next();
+ leafType = type.leafComponentType();
+ erasedSuperTypes[rank++] = (leafType.isTypeVariable() || leafType.isWildcard() /*&& !leafType.isCapture()*/) ? type : type.erasure();
}
// intersecting first type supertypes with other types' ones, nullifying non matching supertypes
int remaining = superLength;
@@ -3052,64 +3125,77 @@
if (otherType == null) continue nextOtherType;
if (otherType.isArrayType()) {
nextSuperType: for (int j = 0; j < superLength; j++) {
- TypeBinding superType = superTypes[j];
- if (superType == null || superType == otherType) continue nextSuperType;
- switch (superType.id) {
- case T_JavaIoSerializable :
- case T_JavaLangCloneable :
- case T_JavaLangObject :
- continue nextSuperType;
+ TypeBinding erasedSuperType = erasedSuperTypes[j];
+ if (erasedSuperType == null || erasedSuperType == otherType) continue nextSuperType;
+ TypeBinding match;
+ if ((match = ((ArrayBinding)otherType).findSuperTypeWithSameErasure(erasedSuperType)) == null) {
+ erasedSuperTypes[j] = null;
+ if (--remaining == 0) return null;
+ continue nextSuperType;
}
- superTypes[j] = null;
- if (--remaining == 0) return null;
-
+ // record invocation
+ Set someInvocations = (Set) allInvocations.get(erasedSuperType);
+ if (someInvocations == null) someInvocations = new HashSet(1);
+ someInvocations.add(match);
+ allInvocations.put(erasedSuperType, someInvocations);
}
continue nextOtherType;
}
ReferenceBinding otherRefType = (ReferenceBinding) otherType;
nextSuperType: for (int j = 0; j < superLength; j++) {
- TypeBinding superType = superTypes[j];
- if (superType == null) continue nextSuperType;
+ TypeBinding erasedSuperType = erasedSuperTypes[j];
+ if (erasedSuperType == null) continue nextSuperType;
TypeBinding match;
- if (superType == otherType || superType.id == T_JavaLangObject && otherType.isInterface()) {
- match = superType;
+ if (erasedSuperType == otherType || erasedSuperType.id == T_JavaLangObject && otherType.isInterface()) {
+ match = erasedSuperType;
} else {
- if (superType.isArrayType()) {
+ if (erasedSuperType.isArrayType()) {
match = null;
} else {
- match = otherRefType.findSuperTypeErasingTo((ReferenceBinding)superType);
+ match = otherRefType.findSuperTypeWithSameErasure(erasedSuperType);
}
if (match == null) { // incompatible super type
- superTypes[j] = null;
+ erasedSuperTypes[j] = null;
if (--remaining == 0) return null;
continue nextSuperType;
}
}
// record invocation
- Set someInvocations = (Set) allInvocations.get(superType);
+ Set someInvocations = (Set) allInvocations.get(erasedSuperType);
if (someInvocations == null) someInvocations = new HashSet(1);
someInvocations.add(match);
- allInvocations.put(superType, someInvocations);
+ allInvocations.put(erasedSuperType, someInvocations);
}
}
// eliminate non minimal super types
if (remaining > 1) {
nextType: for (int i = 0; i < superLength; i++) {
- ReferenceBinding superType = (ReferenceBinding)superTypes[i];
- if (superType == null) continue nextType;
+ TypeBinding erasedSuperType = erasedSuperTypes[i];
+ if (erasedSuperType == null) continue nextType;
nextOtherType: for (int j = 0; j < superLength; j++) {
if (i == j) continue nextOtherType;
- ReferenceBinding otherType = (ReferenceBinding)superTypes[j];
+ TypeBinding otherType = erasedSuperTypes[j];
if (otherType == null) continue nextOtherType;
- if (otherType.id == T_JavaLangObject && superType.isInterface()) continue nextOtherType;
- if (superType.findSuperTypeErasingTo(otherType) != null) {
- superTypes[j] = null; // discard non minimal supertype
- remaining--;
+ if (erasedSuperType instanceof ReferenceBinding) {
+ if (otherType.id == T_JavaLangObject && erasedSuperType.isInterface()) continue nextOtherType; // keep Object for an interface
+ if (((ReferenceBinding)erasedSuperType).findSuperTypeWithSameErasure(otherType) != null) {
+ erasedSuperTypes[j] = null; // discard non minimal supertype
+ remaining--;
+ }
+ } else if (erasedSuperType.isArrayType()) {
+ if (otherType.isArrayType() // keep Object[...] for an interface array (same dimensions)
+ && otherType.leafComponentType().id == T_JavaLangObject
+ && otherType.dimensions() == erasedSuperType.dimensions()
+ && erasedSuperType.leafComponentType().isInterface()) continue nextOtherType;
+ if (((ArrayBinding)erasedSuperType).findSuperTypeWithSameErasure(otherType) != null) {
+ erasedSuperTypes[j] = null; // discard non minimal supertype
+ remaining--;
+ }
}
}
}
}
- return superTypes;
+ return erasedSuperTypes;
}
// Internal use only
@@ -3195,13 +3281,14 @@
for (int i = 0; i < visibleSize; i++)
compatibilityLevels[i] = parameterCompatibilityLevel(visible[i], argumentTypes);
- for (int level = 0; level <= VARARGS_COMPATIBLE; level++) {
+ for (int level = 0, max = VARARGS_COMPATIBLE; level <= max; level++) {
nextVisible : for (int i = 0; i < visibleSize; i++) {
if (compatibilityLevels[i] != level) continue nextVisible; // skip this method for now
MethodBinding method = visible[i];
TypeBinding[] params = method.tiebreakMethod().parameters;
for (int j = 0; j < visibleSize; j++) {
if (i == j || compatibilityLevels[j] != level) continue;
+ max = level; // do not examine further categories
MethodBinding method2 = visible[j];
// tiebreak generic methods using variant where type params are substituted by their erasures
if (!method2.tiebreakMethod().areParametersCompatibleWith(params)) {
@@ -3220,36 +3307,47 @@
continue; // special case to choose between 2 varargs methods when the last arg is missing or its Object[]
}
continue nextVisible;
- } else if (method.hasSubstitutedParameters() && method.isAbstract() == method2.isAbstract()) { // must both be abstract or concrete, not one of each
- if (method.areParametersEqual(method2)) {
- // its possible with 2 abstract methods that one does not inherit from the other
- // need to find their methods from the receiver type
- MethodBinding original = method.original();
- MethodBinding original2 = method2.original();
- if (original.areParameterErasuresEqual(original2)) continue;
- ReferenceBinding receiverType = (ReferenceBinding) ((MessageSend) invocationSite).actualReceiverType;
- if (receiverType != method.declaringClass) {
- ReferenceBinding superType = ((ReferenceBinding) receiverType.erasure()).findSuperTypeErasingTo(original.declaringClass);
- MethodBinding[] superMethods = superType.getMethods(original.selector);
+ }
+
+ // parameterized superclasses & interfaces may be walked twice from different paths
+ if (method.original() == method2.original()) continue;
+
+ // see if method & method2 are duplicates due to the current substitution or multiple static imported methods
+ if (method.tiebreakMethod().areParametersEqual(method2.tiebreakMethod())) {
+ if (method.declaringClass == method2.declaringClass)
+ continue nextVisible; // duplicates thru substitution
+
+ MethodBinding original = method.original();
+ if (method.hasSubstitutedParameters() || original.typeVariables != NoTypeVariables) {
+ ReferenceBinding declaringClass = (ReferenceBinding) method.declaringClass.erasure();
+ ReferenceBinding superType = declaringClass.findSuperTypeWithSameErasure(method2.declaringClass.erasure());
+ if (superType == null) {
+ // accept concrete methods over abstract methods found due to the default abstract method walk
+ if (!method.isAbstract() && method2.isAbstract())
+ continue;
+ continue nextVisible;
+ }
+ MethodBinding inheritedMethod = method2;
+ MethodBinding inheritedOriginal = method2.original();
+ if (method.hasSubstitutedParameters()) { // must find inherited method with the same substituted variables
+ MethodBinding[] superMethods = superType.getMethods(inheritedMethod.selector);
for (int m = 0, l = superMethods.length; m < l; m++) {
- if (superMethods[m].original() == original) {
- original = superMethods[m];
+ if (superMethods[m].original() == inheritedOriginal) {
+ inheritedMethod = superMethods[m];
break;
}
}
}
- if (receiverType != method2.declaringClass) {
- ReferenceBinding superType = ((ReferenceBinding) receiverType.erasure()).findSuperTypeErasingTo(original2.declaringClass);
- MethodBinding[] superMethods = superType.getMethods(original2.selector);
- for (int m = 0, l = superMethods.length; m < l; m++) {
- if (superMethods[m].original() == original2) {
- original2 = superMethods[m];
- break;
- }
- }
- }
- if (!original.areParametersEqual(original2))
- continue nextVisible; // cannot be substituted from 2 different type variables
+ if (original.typeVariables != NoTypeVariables)
+ inheritedMethod = original.computeSubstitutedMethod(inheritedMethod == method2 ? inheritedOriginal : inheritedMethod, environment());
+ if (inheritedMethod == null || !original.areParametersEqual(inheritedMethod))
+ break nextVisible; // dup thru substitution, not overridden... cannot find possible match
+ // method overrides method2, accept it
+ } else if (method.isStatic() && method2.isStatic()) {
+ ReferenceBinding declaringClass = (ReferenceBinding) method.declaringClass.erasure();
+ ReferenceBinding superType = declaringClass.findSuperTypeWithSameErasure(method2.declaringClass.erasure());
+ if (superType == null)
+ continue nextVisible; // static methods from unrelated types
}
}
}
@@ -3287,8 +3385,7 @@
int paramLength = parameters.length;
int argLength = arguments.length;
- LookupEnvironment env = environment();
- if (env.options.sourceLevel < ClassFileConstants.JDK1_5) {
+ if (compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) {
if (paramLength != argLength)
return NOT_COMPATIBLE;
for (int i = 0; i < argLength; i++) {
@@ -3308,11 +3405,11 @@
TypeBinding param = parameters[lastIndex]; // is an ArrayBinding by definition
TypeBinding arg = arguments[lastIndex];
if (param != arg) {
- level = parameterCompatibilityLevel(arg, param, env);
+ level = parameterCompatibilityLevel(arg, param, environment());
if (level == NOT_COMPATIBLE) {
// expect X[], is it called with X
param = ((ArrayBinding) param).elementsType();
- if (parameterCompatibilityLevel(arg, param, env) == NOT_COMPATIBLE)
+ if (parameterCompatibilityLevel(arg, param, environment()) == NOT_COMPATIBLE)
return NOT_COMPATIBLE;
level = VARARGS_COMPATIBLE; // varargs support needed
}
@@ -3322,7 +3419,7 @@
TypeBinding param = ((ArrayBinding) parameters[lastIndex]).elementsType();
for (int i = lastIndex; i < argLength; i++) {
TypeBinding arg = arguments[i];
- if (param != arg && parameterCompatibilityLevel(arg, param, env) == NOT_COMPATIBLE)
+ if (param != arg && parameterCompatibilityLevel(arg, param, environment()) == NOT_COMPATIBLE)
return NOT_COMPATIBLE;
}
} else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
@@ -3336,7 +3433,7 @@
TypeBinding param = parameters[i];
TypeBinding arg = arguments[i];
if (arg != param) {
- int newLevel = parameterCompatibilityLevel(arg, param, env);
+ int newLevel = parameterCompatibilityLevel(arg, param, environment());
if (newLevel == NOT_COMPATIBLE)
return NOT_COMPATIBLE;
if (newLevel > level)
@@ -3366,6 +3463,26 @@
unitScope = scope;
return ((CompilationUnitScope) unitScope).referenceContext;
}
+
+ /**
+ * Returns the nearest reference context, starting from current scope.
+ * If starting on a class, it will return current class. If starting on unitScope, returns unit.
+ */
+ public ReferenceContext referenceContext() {
+ Scope current = this;
+ do {
+ switch(current.kind) {
+ case METHOD_SCOPE :
+ return ((MethodScope) current).referenceContext;
+ case CLASS_SCOPE :
+ return ((ClassScope) current).referenceContext;
+ case COMPILATION_UNIT_SCOPE :
+ return ((CompilationUnitScope) current).referenceContext;
+ }
+ } while ((current = current.parent) != null);
+ return null;
+ }
+
// start position in this scope - for ordering scopes vs. variables
int startIndex() {
return 0;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 7f164d3..e72a89c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -80,7 +80,7 @@
tagBits |= KnowsDefaultAbstractMethods;
if (isClass() && isAbstract()) {
- if (fPackage.environment.options.targetJDK >= ClassFileConstants.JDK1_2)
+ if (this.scope.compilerOptions().targetJDK >= ClassFileConstants.JDK1_2)
return; // no longer added for post 1.2 targets
ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
@@ -185,7 +185,7 @@
for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
FieldDeclaration fieldDecl = typeDecl.fields[i];
if (fieldDecl.binding == existingField) {
- if (this.scope.environment().options.complianceLevel >= ClassFileConstants.JDK1_5) {
+ if (this.scope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_5) {
synthField.name = CharOperation.concat(
synthField.name,
"$".toCharArray()); //$NON-NLS-1$
@@ -369,6 +369,78 @@
}
return accessMethod;
}
+/*
+ * Add a synthetic field to handle the cache of the switch translation table for the corresponding enum type
+ */
+public SyntheticFieldBinding addSyntheticFieldForSwitchEnum(char[] fieldName, String key) {
+ if (synthetics == null)
+ synthetics = new HashMap[4];
+ if (synthetics[FIELD_EMUL] == null)
+ synthetics[FIELD_EMUL] = new HashMap(5);
+
+ SyntheticFieldBinding synthField = (SyntheticFieldBinding) synthetics[FIELD_EMUL].get(key); //$NON-NLS-1$
+ if (synthField == null) {
+ synthField = new SyntheticFieldBinding(
+ fieldName,
+ scope.createArrayType(BaseTypes.IntBinding,1),
+ AccPrivate | AccStatic | AccSynthetic,
+ this,
+ Constant.NotAConstant,
+ synthetics[FIELD_EMUL].size());
+ synthetics[FIELD_EMUL].put(key, synthField);
+ }
+ // ensure there is not already such a field defined by the user
+ boolean needRecheck;
+ int index = 0;
+ do {
+ needRecheck = false;
+ FieldBinding existingField;
+ if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
+ TypeDeclaration typeDecl = scope.referenceContext;
+ for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
+ FieldDeclaration fieldDecl = typeDecl.fields[i];
+ if (fieldDecl.binding == existingField) {
+ synthField.name = CharOperation.concat(
+ fieldName,
+ ("_" + String.valueOf(index++)).toCharArray()); //$NON-NLS-1$
+ needRecheck = true;
+ break;
+ }
+ }
+ }
+ } while (needRecheck);
+ return synthField;
+}
+/* Add a new synthetic method the enum type. Selector can either be 'values' or 'valueOf'.
+ * char[] constants from TypeConstants must be used: TypeConstants.VALUES/VALUEOF
+*/
+public SyntheticMethodBinding addSyntheticMethodForSwitchEnum(TypeBinding enumBinding) {
+ if (synthetics == null)
+ synthetics = new HashMap[4];
+ if (synthetics[METHOD_EMUL] == null)
+ synthetics[METHOD_EMUL] = new HashMap(5);
+
+ SyntheticMethodBinding accessMethod = null;
+ char[] selector = CharOperation.concat(TypeConstants.SYNTHETIC_SWITCH_ENUM_TABLE, enumBinding.constantPoolName());
+ CharOperation.replace(selector, '/', '$');
+ final String key = new String(selector);
+ SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) synthetics[METHOD_EMUL].get(key);
+ // first add the corresponding synthetic field
+ if (accessors == null) {
+ // then create the synthetic method
+ final SyntheticFieldBinding fieldBinding = this.addSyntheticFieldForSwitchEnum(selector, key);
+ accessMethod = new SyntheticMethodBinding(fieldBinding, this, enumBinding, selector);
+ synthetics[METHOD_EMUL].put(key, accessors = new SyntheticMethodBinding[2]);
+ accessors[0] = accessMethod;
+ } else {
+ if ((accessMethod = accessors[0]) == null) {
+ final SyntheticFieldBinding fieldBinding = this.addSyntheticFieldForSwitchEnum(selector, key);
+ accessMethod = new SyntheticMethodBinding(fieldBinding, this, enumBinding, selector);
+ accessors[0] = accessMethod;
+ }
+ }
+ return accessMethod;
+}
/* Add a new synthetic access method for access to <targetMethod>.
* Must distinguish access method used for super access from others (need to use invokespecial bytecode)
Answer the new method or the existing method if one already existed.
@@ -454,12 +526,12 @@
case CONSTRAINT_EQUAL :
case CONSTRAINT_EXTENDS :
equivalent = this;
- otherEquivalent = ((ReferenceBinding)otherType).findSuperTypeErasingTo(this);
+ otherEquivalent = ((ReferenceBinding)otherType).findSuperTypeWithSameErasure(this);
if (otherEquivalent == null) return;
break;
case CONSTRAINT_SUPER :
default:
- equivalent = this.findSuperTypeErasingTo((ReferenceBinding)(otherType.erasure()));
+ equivalent = this.findSuperTypeWithSameErasure(otherType);
if (equivalent == null) return;
otherEquivalent = (ReferenceBinding) otherType;
break;
@@ -500,8 +572,8 @@
if (this.typeVariables != NoTypeVariables) return Binding.GENERIC_TYPE;
return Binding.TYPE;
}
-public char[] computeUniqueKey(boolean withAccessFlags) {
- char[] uniqueKey = super.computeUniqueKey(withAccessFlags);
+public char[] computeUniqueKey(boolean isLeaf) {
+ char[] uniqueKey = super.computeUniqueKey(isLeaf);
if (uniqueKey.length == 2) return uniqueKey; // problem type's unique key is "L;"
int start = CharOperation.lastIndexOf('/', this.fileName) + 1;
int end = CharOperation.lastIndexOf('.', this.fileName);
@@ -535,7 +607,7 @@
// check @Deprecated annotation
if ((this.getAnnotationTagBits() & AnnotationDeprecated) != 0) {
this.modifiers |= AccDeprecated;
- } else if ((this.modifiers & AccDeprecated) != 0 && scope != null && scope.environment().options.sourceLevel >= JDK1_5) {
+ } else if ((this.modifiers & AccDeprecated) != 0 && scope != null && scope.compilerOptions().sourceLevel >= JDK1_5) {
scope.problemReporter().missingDeprecatedAnnotationForType(scope.referenceContext);
}
ReferenceBinding enclosingType = this.enclosingType();
@@ -781,10 +853,11 @@
MethodBinding[] result = new MethodBinding[matchingMethods.size()];
matchingMethods.toArray(result);
if (!methodsAreResolved) {
+ boolean isSource15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
for (int i = 0, length = result.length - 1; i < length; i++) {
MethodBinding method = result[i];
for (int j = length; j > i; j--) {
- boolean paramsMatch = fPackage.environment.options.sourceLevel >= ClassFileConstants.JDK1_5
+ boolean paramsMatch = isSource15
? method.areParameterErasuresEqual(result[j])
: method.areParametersEqual(result[j]);
if (paramsMatch) {
@@ -820,7 +893,7 @@
while (accessFields.hasNext()) {
field = (FieldBinding) accessFields.next();
if (CharOperation.prefixEquals(TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX, field.name)
- && ((ReferenceBinding) field.type).findSuperTypeErasingTo(targetEnclosingType) != null)
+ && ((ReferenceBinding) field.type).findSuperTypeWithSameErasure(targetEnclosingType) != null)
return field;
}
}
@@ -856,9 +929,16 @@
if (this != otherParamType.type)
return false;
if (!isStatic()) { // static member types do not compare their enclosing
- ReferenceBinding enclosing = enclosingType();
- if (enclosing != null && !enclosing.isEquivalentTo(otherParamType.enclosingType()))
- return false;
+ ReferenceBinding enclosing = enclosingType();
+ if (enclosing != null) {
+ ReferenceBinding otherEnclosing = otherParamType.enclosingType();
+ if (otherEnclosing == null) return false;
+ if ((otherEnclosing.tagBits & HasDirectWildcard) == 0) {
+ if (enclosing != otherEnclosing) return false;
+ } else {
+ if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false;
+ }
+ }
}
int length = this.typeVariables == null ? 0 : this.typeVariables.length;
TypeBinding[] otherArguments = otherParamType.arguments;
@@ -935,27 +1015,68 @@
}
// find & report collision cases
- boolean complyTo15 = fPackage.environment.options.sourceLevel >= ClassFileConstants.JDK1_5;
+ boolean complyTo15 = this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5;
for (int i = 0, length = methods.length; i < length; i++) {
MethodBinding method = methods[i];
if (method != null) {
- TypeBinding returnErasure = method.returnType == null ? null : method.returnType.erasure();
char[] selector = method.selector;
AbstractMethodDeclaration methodDecl = null;
nextMethod : for (int j = length - 1; j > i; j--) {
MethodBinding method2 = methods[j];
if (method2 == null || !CharOperation.equals(selector, method2.selector))
continue nextMethod;
- if (complyTo15) {
- if (returnErasure != (method2.returnType == null ? null : method2.returnType.erasure())) {
- // colllision when parameters are identical & type variable erasures match
- if (!method.areParametersEqual(method2))
- continue nextMethod;
- if (method.typeVariables != NoTypeVariables && method2.typeVariables != NoTypeVariables)
- if (!method.areTypeVariableErasuresEqual(method2))
- continue nextMethod;
- } else if (!method.areParameterErasuresEqual(method2)) { // colllision when parameter & return type erasures match
+ if (complyTo15 && method.returnType != null && method2.returnType != null) {
+ // 8.4.2, for collision to be detected between m1 and m2:
+ // signature(m1) == signature(m2) i.e. same arity, same type parameter count, can be substituted
+ // signature(m1) == erasure(signature(m2)) or erasure(signature(m1)) == signature(m2)
+ TypeBinding[] params1 = method.parameters;
+ TypeBinding[] params2 = method2.parameters;
+ int pLength = params1.length;
+ if (pLength != params2.length)
continue nextMethod;
+
+ TypeVariableBinding[] vars = method.typeVariables;
+ TypeVariableBinding[] vars2 = method2.typeVariables;
+ boolean equalTypeVars = vars == vars2;
+ MethodBinding subMethod = method2;
+ if (!equalTypeVars) {
+ MethodBinding temp = method.computeSubstitutedMethod(method2, this.scope.environment());
+ if (temp != null) {
+ equalTypeVars = true;
+ subMethod = temp;
+ }
+ }
+ boolean equalParams = method.areParametersEqual(subMethod);
+ if (equalParams && equalTypeVars) {
+ // duplicates regardless of return types
+ } else if (method.returnType.erasure() == subMethod.returnType.erasure() && (equalParams || method.areParameterErasuresEqual(method2))) {
+ // name clash for sure if not duplicates, report as duplicates
+ } else if (!equalTypeVars && vars != NoTypeVariables && vars2 != NoTypeVariables) {
+ // type variables are different so we can distinguish between methods
+ continue nextMethod;
+ } else if (pLength > 0) {
+ // check to see if the erasure of either method is equal to the other
+ int index = pLength;
+ for (; --index >= 0;) {
+ if (params1[index] != params2[index].erasure())
+ if (!params1[index].isRawType() || params1[index].erasure() != params2[index].erasure()) // want X#RAW to match X#RAW and X<T>
+ break;
+ if (params1[index] == params2[index]) {
+ TypeBinding type = params1[index].leafComponentType();
+ if (type instanceof SourceTypeBinding && type.typeVariables() != NoTypeVariables) {
+ index = pLength; // handle comparing identical source types like X<T>... its erasure is itself BUT we need to answer false
+ break;
+ }
+ }
+ }
+ if (index >= 0 && index < pLength) {
+ for (index = pLength; --index >= 0;)
+ if (params1[index].erasure() != params2[index])
+ if (!params2[index].isRawType() || params1[index].erasure() != params2[index].erasure()) // want X#RAW to match X#RAW and X<T>
+ break;
+ }
+ if (index >= 0)
+ continue nextMethod;
}
} else if (!method.areParametersEqual(method2)) { // prior to 1.5, parameter identity meant a collision case
continue nextMethod;
@@ -987,7 +1108,7 @@
failed++;
}
}
- if (returnErasure == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions
+ if (method.returnType == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions
method.sourceMethod().binding = null;
methods[i] = null;
failed++;
@@ -1018,11 +1139,11 @@
if ((field.modifiers & AccUnresolved) == 0)
return field;
- if (fPackage.environment.options.sourceLevel >= ClassFileConstants.JDK1_5) {
+ if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
if ((field.getAnnotationTagBits() & AnnotationDeprecated) != 0)
field.modifiers |= AccDeprecated;
else if ((field.modifiers & AccDeprecated) != 0)
- scope.problemReporter().missingDeprecatedAnnotationForField(field.sourceField());
+ this.scope.problemReporter().missingDeprecatedAnnotationForField(field.sourceField());
}
if (isViewedAsDeprecated() && !field.isDeprecated())
field.modifiers |= AccDeprecatedImplicitly;
@@ -1032,15 +1153,15 @@
continue;
MethodScope initializationScope = field.isStatic()
- ? scope.referenceContext.staticInitializerScope
- : scope.referenceContext.initializerScope;
+ ? this.scope.referenceContext.staticInitializerScope
+ : this.scope.referenceContext.initializerScope;
FieldBinding previousField = initializationScope.initializedField;
try {
initializationScope.initializedField = field;
FieldDeclaration fieldDecl = fieldDecls[f];
TypeBinding fieldType =
fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT
- ? this // enum constant is implicitly of declaring enum type
+ ? initializationScope.environment().convertToRawType(this) // enum constant is implicitly of declaring enum type
: fieldDecl.type.resolveType(initializationScope, true /* check bounds*/);
field.type = fieldType;
field.modifiers &= ~AccUnresolved;
@@ -1073,11 +1194,11 @@
if ((method.modifiers & AccUnresolved) == 0)
return method;
- if (fPackage.environment.options.sourceLevel >= ClassFileConstants.JDK1_5) {
+ if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
if ((method.getAnnotationTagBits() & AnnotationDeprecated) != 0)
method.modifiers |= AccDeprecated;
else if ((method.modifiers & AccDeprecated) != 0)
- scope.problemReporter().missingDeprecatedAnnotationForMethod(method.sourceMethod());
+ this.scope.problemReporter().missingDeprecatedAnnotationForMethod(method.sourceMethod());
}
if (isViewedAsDeprecated() && !method.isDeprecated())
method.modifiers |= AccDeprecatedImplicitly;
@@ -1096,14 +1217,14 @@
if (exceptionTypes != null) {
int size = exceptionTypes.length;
method.thrownExceptions = new ReferenceBinding[size];
- ReferenceBinding throwable = scope.getJavaLangThrowable();
+ ReferenceBinding throwable = this.scope.getJavaLangThrowable();
int count = 0;
ReferenceBinding resolvedExceptionType;
for (int i = 0; i < size; i++) {
resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].resolveType(methodDecl.scope, true /* check bounds*/);
if (resolvedExceptionType == null)
continue;
- if (resolvedExceptionType.isGenericType() || resolvedExceptionType.isParameterizedType()) {
+ if (resolvedExceptionType.isGenericType() || resolvedExceptionType.isBoundParameterizedType()) {
methodDecl.scope.problemReporter().invalidParameterizedExceptionType(resolvedExceptionType, exceptionTypes[i]);
continue;
}
@@ -1294,7 +1415,10 @@
if (isStatic() && isNestedType()) buffer.append("static "); //$NON-NLS-1$
if (isFinal()) buffer.append("final "); //$NON-NLS-1$
- buffer.append(isInterface() ? "interface " : "class "); //$NON-NLS-1$ //$NON-NLS-2$
+ if (isEnum()) buffer.append("enum "); //$NON-NLS-1$
+ else if (isAnnotationType()) buffer.append("@interface "); //$NON-NLS-1$
+ else if (isClass()) buffer.append("class "); //$NON-NLS-1$
+ else buffer.append("interface "); //$NON-NLS-1$
buffer.append((compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED TYPE"); //$NON-NLS-1$
if (this.typeVariables == null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
index 0f10dd6..299a4ee 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
@@ -18,7 +18,8 @@
public FieldBinding targetReadField; // read access to a field
public FieldBinding targetWriteField; // write access to a field
- public MethodBinding targetMethod; // method or constructor
+ public MethodBinding targetMethod; // method or constructor
+ public TypeBinding targetEnumType; // enum type
public int kind;
@@ -30,6 +31,7 @@
public final static int BridgeMethod = 6; // bridge method
public final static int EnumValues = 7; // enum #values()
public final static int EnumValueOf = 8; // enum #valueOf(String)
+ public final static int SwitchTable = 9; // switch table method
public int sourceStart = 0; // start position of the matching declaration
public int index; // used for sorting access methods in the class file
@@ -128,6 +130,59 @@
this.sourceStart = declaringSourceType.scope.referenceContext.sourceStart; // use the target declaring class name position instead
}
+ public SyntheticMethodBinding(FieldBinding targetField, ReferenceBinding declaringClass, TypeBinding enumBinding, char[] selector) {
+ this.modifiers = AccDefault | AccStatic | AccSynthetic;
+ this.tagBits |= TagBits.AnnotationResolved;
+ SourceTypeBinding declaringSourceType = (SourceTypeBinding) declaringClass;
+ SyntheticMethodBinding[] knownAccessMethods = declaringSourceType.syntheticMethods();
+ int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+ this.index = methodId;
+ this.selector = selector;
+ this.returnType = declaringSourceType.scope.createArrayType(BaseTypes.IntBinding, 1);
+ this.parameters = NoParameters;
+ this.targetReadField = targetField;
+ this.targetEnumType = enumBinding;
+ this.kind = SwitchTable;
+ this.thrownExceptions = NoExceptions;
+ this.declaringClass = declaringSourceType;
+
+ if (declaringSourceType.isStrictfp()) {
+ this.modifiers |= AccStrictfp;
+ }
+ // check for method collision
+ boolean needRename;
+ do {
+ check : {
+ needRename = false;
+ // check for collision with known methods
+ MethodBinding[] methods = declaringSourceType.methods;
+ for (int i = 0, length = methods.length; i < length; i++) {
+ if (CharOperation.equals(this.selector, methods[i].selector) && this.areParametersEqual(methods[i])) {
+ needRename = true;
+ break check;
+ }
+ }
+ // check for collision with synthetic accessors
+ if (knownAccessMethods != null) {
+ for (int i = 0, length = knownAccessMethods.length; i < length; i++) {
+ if (knownAccessMethods[i] == null) continue;
+ if (CharOperation.equals(this.selector, knownAccessMethods[i].selector) && this.areParametersEqual(methods[i])) {
+ needRename = true;
+ break check;
+ }
+ }
+ }
+ }
+ if (needRename) { // retry with a selector postfixed by a growing methodId
+ this.setSelector(CharOperation.concat(selector, String.valueOf(++methodId).toCharArray()));
+ }
+ } while (needRename);
+
+ // We now at this point - per construction - it is for sure an enclosing instance, we are going to
+ // show the target field type declaration location.
+ this.sourceStart = declaringSourceType.scope.referenceContext.sourceStart; // use the target declaring class name position instead
+ }
+
public SyntheticMethodBinding(MethodBinding targetMethod, boolean isSuperAccess, ReferenceBinding receiverType) {
if (targetMethod.isConstructor()) {
@@ -144,9 +199,9 @@
this.declaringClass = declaringClass;
this.selector = overridenMethodToBridge.selector;
- this.modifiers = overridenMethodToBridge.modifiers | AccBridge | AccSynthetic;
+ // amongst other, clear the AccGenericSignature, so as to ensure no remains of original inherited persist (101794)
+ this.modifiers = (overridenMethodToBridge.modifiers | AccBridge | AccSynthetic) & ~(AccAbstract | AccNative | AccGenericSignature);
this.tagBits |= TagBits.AnnotationResolved;
- this.modifiers &= ~(AccAbstract | AccNative);
this.returnType = overridenMethodToBridge.returnType;
this.parameters = overridenMethodToBridge.parameters;
this.thrownExceptions = overridenMethodToBridge.thrownExceptions;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
index d525014..16525e5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
@@ -47,6 +47,9 @@
// test bit to identify if the type's hierarchy is inconsistent
long HierarchyHasProblems = ASTNode.Bit16;
+ // set for parameterized type with successfull bound check
+ long PassedBoundCheck = ASTNode.Bit23;
+
// set for parameterized type NOT of the form X<?,?>
long IsBoundParameterizedType = ASTNode.Bit24;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
index eb1201d..cce5926 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
@@ -72,7 +72,7 @@
/**
* Perform capture conversion on a given type (only effective on parameterized type with wildcards)
*/
-public TypeBinding capture() {
+public TypeBinding capture(Scope scope, int position) {
return this;
}
@@ -127,6 +127,10 @@
return signature();
}
public abstract PackageBinding getPackage();
+
+public final boolean isAnonymousType() {
+ return (tagBits & IsAnonymousType) != 0;
+}
public boolean isAnnotationType() {
return false;
}
@@ -190,6 +194,18 @@
public boolean isInterface() {
return false;
}
+/**
+ * Returns true if a type is intersecting with another one,
+ */
+public boolean isIntersectingWith(TypeBinding otherType) {
+ return this == otherType;
+}
+/**
+ * Returns true if the current type denotes an intersection type: Number & Comparable<?>
+ */
+public boolean isIntersectionType() {
+ return false;
+}
public final boolean isLocalType() {
return (tagBits & IsLocalType) != 0;
}
@@ -307,50 +323,251 @@
}
// JLS3: 4.5.1.1
-public boolean isTypeArgumentContainedBy(TypeBinding otherArgument) {
- if (this == otherArgument)
+public boolean isTypeArgumentContainedBy(TypeBinding otherType) {
+ if (this == otherType)
return true;
- TypeBinding lowerBound = this;
- TypeBinding upperBound = this;
- if (isWildcard()) {
- WildcardBinding wildcard = (WildcardBinding) this;
- switch(wildcard.boundKind) {
- case Wildcard.EXTENDS :
- upperBound = wildcard.bound;
- lowerBound = null;
- break;
- case Wildcard. SUPER :
- upperBound = wildcard.typeVariable();
- lowerBound = wildcard.bound;
- break;
- case Wildcard.UNBOUND :
- upperBound = wildcard.typeVariable();
- lowerBound = null;
- }
- }
- if (otherArgument.isWildcard()) {
- WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
- if (otherWildcard.otherBounds != null) return false; // not a true wildcard (intersection type)
- switch(otherWildcard.boundKind) {
- case Wildcard.EXTENDS:
- return upperBound != null && upperBound.isCompatibleWith(otherWildcard.bound);
-
- case Wildcard.SUPER :
- return lowerBound != null && otherWildcard.bound.isCompatibleWith(lowerBound);
-
- case Wildcard.UNBOUND :
- return true;
- }
+ switch(otherType.kind()) {
+ // allow wildcard containment
+ case Binding.WILDCARD_TYPE :
+ TypeBinding lowerBound = this;
+ TypeBinding upperBound = this;
+ switch (this.kind()) {
+ case Binding.WILDCARD_TYPE :
+ WildcardBinding wildcard = (WildcardBinding) this;
+ switch(wildcard.boundKind) {
+ case Wildcard.EXTENDS :
+ upperBound = wildcard.bound;
+ lowerBound = null;
+ break;
+ case Wildcard. SUPER :
+ upperBound = wildcard;
+ lowerBound = wildcard.bound;
+ break;
+ case Wildcard.UNBOUND :
+ upperBound = wildcard;
+ lowerBound = null;
+ }
+ break;
+ case Binding.TYPE_PARAMETER :
+ if (this.isCapture()) {
+ CaptureBinding capture = (CaptureBinding) this;
+ if (capture.lowerBound != null) lowerBound = capture.lowerBound;
+ }
+ }
+ WildcardBinding otherWildcard = (WildcardBinding) otherType;
+ if (otherWildcard.otherBounds != null) return false; // not a true wildcard (intersection type)
+ switch(otherWildcard.boundKind) {
+ case Wildcard.EXTENDS:
+ if (otherWildcard.bound == this) return true; // ? extends T <= ? extends ? extends T
+ return upperBound != null && upperBound.isCompatibleWith(otherWildcard.bound);
+
+ case Wildcard.SUPER :
+ if (otherWildcard.bound == this) return true; // ? super T <= ? super ? super T
+ return lowerBound != null && otherWildcard.bound.isCompatibleWith(lowerBound);
+
+ case Wildcard.UNBOUND :
+ default:
+ return true;
+ }
+ // allow List<?> to match List<? extends Object> (and reciprocally)
+ case Binding.PARAMETERIZED_TYPE :
+ if (!this.isParameterizedType()) return false;
+ ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) this;
+ ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
+ if (paramType.type != otherParamType.type)
+ return false;
+ if (!paramType.isStatic()) { // static member types do not compare their enclosing
+ ReferenceBinding enclosing = enclosingType();
+ if (enclosing != null) {
+ ReferenceBinding otherEnclosing = otherParamType.enclosingType();
+ if (otherEnclosing == null) return false;
+ if ((otherEnclosing.tagBits & HasDirectWildcard) == 0) {
+ if (enclosing != otherEnclosing) return false;
+ } else {
+ if (!enclosing.isEquivalentTo(otherParamType.enclosingType())) return false;
+ }
+ }
+ }
+ int length = paramType.arguments == null ? 0 : paramType.arguments.length;
+ TypeBinding[] otherArguments = otherParamType.arguments;
+ int otherLength = otherArguments == null ? 0 : otherArguments.length;
+ if (otherLength != length)
+ return false;
+ nextArgument: for (int i = 0; i < length; i++) {
+ TypeBinding argument = paramType.arguments[i];
+ TypeBinding otherArgument = otherArguments[i];
+ if (argument == otherArgument)
+ continue nextArgument;
+ int kind = argument.kind();
+ if (otherArgument.kind() != kind)
+ return false;
+ switch(kind) {
+ case Binding.PARAMETERIZED_TYPE :
+ if (argument.isTypeArgumentContainedBy(otherArgument)) // recurse
+ continue nextArgument;
+ break;
+ case Binding.WILDCARD_TYPE :
+ WildcardBinding wildcard = (WildcardBinding) argument;
+ otherWildcard = (WildcardBinding) otherArgument;
+ switch (wildcard.boundKind) {
+ case Wildcard.EXTENDS :
+ // match "? extends <upperBound>" with "?"
+ if (otherWildcard.boundKind == Wildcard.UNBOUND && wildcard.bound == wildcard.typeVariable().upperBound())
+ continue nextArgument;
+ break;
+ case Wildcard.SUPER :
+ break;
+ case Wildcard.UNBOUND :
+ // match "?" with "? extends <upperBound>"
+ if (otherWildcard.boundKind == Wildcard.EXTENDS && otherWildcard.bound == otherWildcard.typeVariable().upperBound())
+ continue nextArgument;
+ break;
+ }
+ break;
+ }
+ return false;
+ }
+ return true;
}
return false;
}
/**
+ * Returns false if two given types could not intersect as argument types:
+ * List<Throwable> & List<Runnable> --> false
+ * List<? extends Throwable> & List<? extends Runnable> --> true
+ * List<? extends String> & List<? extends Runnable> --> false
+ */
+public boolean isTypeArgumentIntersecting(TypeBinding otherArgument) {
+ if (this == otherArgument)
+ return true;
+ switch (kind()) {
+
+ // TYPE_PARAM & ANY TYPE
+ case Binding.TYPE_PARAMETER :
+ return true;
+
+ case Binding.WILDCARD_TYPE :
+ switch (otherArgument.kind()) {
+
+ // WILDCARD & TYPE_PARAM
+ case Binding.TYPE_PARAMETER :
+ return true;
+
+ // WILDCARD & WILDCARD
+ case Binding.WILDCARD_TYPE :
+ TypeBinding lowerBound1 = null;
+ TypeBinding upperBound1 = null;
+ WildcardBinding wildcard = (WildcardBinding) this;
+ switch(wildcard.boundKind) {
+ case Wildcard.EXTENDS :
+ upperBound1 = wildcard.bound;
+ break;
+ case Wildcard. SUPER :
+ lowerBound1 = wildcard.bound;
+ break;
+ case Wildcard.UNBOUND :
+ }
+
+ TypeBinding lowerBound2 = null;
+ TypeBinding upperBound2 = null;
+ WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
+ switch(otherWildcard.boundKind) {
+ case Wildcard.EXTENDS :
+ upperBound2 = otherWildcard.bound;
+ break;
+ case Wildcard. SUPER :
+ lowerBound2 = otherWildcard.bound;
+ break;
+ case Wildcard.UNBOUND :
+ }
+ if (lowerBound1 != null) {
+ if (lowerBound2 != null) {
+ return true; // Object could always be a candidate
+
+ } else if (upperBound2 != null) {
+ return lowerBound1.isCompatibleWith(upperBound2);
+ } else {
+ return true;
+ }
+ } else if (upperBound1 != null) {
+ if (upperBound1.isTypeVariable()) return true;
+ if (lowerBound2 != null) {
+ return lowerBound2.isCompatibleWith(upperBound1);
+
+ } else if (upperBound2 != null) {
+ if (upperBound1.isInterface()) {
+ if (upperBound2.isInterface())
+ return true;
+ if (upperBound2.isArrayType() || ((upperBound2 instanceof ReferenceBinding) && ((ReferenceBinding)upperBound2).isFinal())) {
+ return upperBound2.isCompatibleWith(upperBound1);
+ }
+ return true;
+ } else {
+ if (upperBound2.isInterface()) {
+ if (upperBound1.isArrayType() || ((upperBound1 instanceof ReferenceBinding) && ((ReferenceBinding)upperBound1).isFinal())) {
+ return upperBound1.isCompatibleWith(upperBound2);
+ }
+ } else {
+ return upperBound1.isCompatibleWith(upperBound2);
+ }
+ }
+ return true;
+ } else {
+ return true;
+ }
+ } else {
+ return true;
+ }
+
+ // WILDCARD & OTHER TYPE
+ default :
+ wildcard = (WildcardBinding) this;
+ switch(wildcard.boundKind) {
+ case Wildcard.EXTENDS :
+ return otherArgument.isCompatibleWith(wildcard.bound);
+ case Wildcard. SUPER :
+ return wildcard.bound.isCompatibleWith(otherArgument);
+ case Wildcard.UNBOUND :
+ default:
+ return true;
+ }
+ }
+
+ default:
+ switch (otherArgument.kind()) {
+
+ // OTHER TYPE & TYPE_PARAM
+ case Binding.TYPE_PARAMETER :
+ return true;
+
+ // OTHER TYPE & WILDCARD
+ case Binding.WILDCARD_TYPE :
+ WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
+ switch(otherWildcard.boundKind) {
+ case Wildcard.EXTENDS :
+ return this.isCompatibleWith(otherWildcard.bound);
+ case Wildcard. SUPER :
+ return otherWildcard.bound.isCompatibleWith(this);
+ case Wildcard.UNBOUND :
+ default:
+ return true;
+ }
+
+ // OTHER TYPE & OTHER TYPE
+ default :
+ return false;
+ }
+ }
+}
+
+/**
* Returns true if the type was declared as a type variable
*/
public boolean isTypeVariable() {
return false;
}
+
/**
* Returns true if wildcard type of the form '?' (no bound)
*/
@@ -359,6 +576,13 @@
}
/**
+ * Returns true if the type is a subclass of java.lang.Error or java.lang.RuntimeException
+ */
+public boolean isUncheckedException(boolean includeSupertype) {
+ return false;
+}
+
+/**
* Returns true if the type is a wildcard
*/
public boolean isWildcard() {
@@ -379,15 +603,18 @@
if (!(currentType instanceof ReferenceBinding))
return false;
- ReferenceBinding compatible = ((ReferenceBinding)currentType).findSuperTypeErasingTo((ReferenceBinding)targetType.erasure());
+ ReferenceBinding compatible = ((ReferenceBinding)currentType).findSuperTypeWithSameErasure(targetType);
if (compatible == null)
return false;
- if (!compatible.isPartOfRawType()) return false;
- do {
- if (compatible.isRawType() && (targetType.isBoundParameterizedType() || targetType.isGenericType())) {
+
+ while (compatible.isRawType()) {
+ if (targetType.isBoundParameterizedType() || targetType.isGenericType()) {
return true;
}
- } while ((compatible = compatible.enclosingType()) != null && (targetType = targetType.enclosingType()) != null);
+ if (compatible.isStatic()) break;
+ if ((compatible = compatible.enclosingType()) == null) break;
+ if ((targetType = targetType.enclosingType()) == null) break;
+ }
return false;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
index a154f81..c40ed9e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
@@ -144,6 +144,7 @@
// Synthetics
char[] INIT = "<init>".toCharArray(); //$NON-NLS-1$
char[] CLINIT = "<clinit>".toCharArray(); //$NON-NLS-1$
+ char[] SYNTHETIC_SWITCH_ENUM_TABLE = "$SWITCH_TABLE$".toCharArray(); //$NON-NLS-1$
char[] SYNTHETIC_ENUM_VALUES = "ENUM$VALUES".toCharArray(); //$NON-NLS-1$
char[] SYNTHETIC_ASSERT_DISABLED = "$assertionsDisabled".toCharArray(); //$NON-NLS-1$
char[] SYNTHETIC_CLASS = "class$".toCharArray(); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
index 821214e..7d43e8e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
@@ -40,7 +40,7 @@
final int T_JavaLangThrowable = 21;
final int T_JavaLangNoClassDefError = 22;
final int T_JavaLangClassNotFoundException = 23;
- final int T_JavaIoPrintStream = 24;
+ final int T_JavaLangRuntimeException = 24;
final int T_JavaLangException = 25;
// wrapper types
@@ -77,7 +77,9 @@
final int T_JavaLangAnnotationTarget = 50;
final int T_JavaLangAnnotationRetentionPolicy = 51;
final int T_JavaLangAnnotationElementType = 52;
-
+
+ final int T_JavaIoPrintStream = 53;
+
final int NoId = Integer.MAX_VALUE;
public static final int IMPLICIT_CONVERSION_MASK = 0xFF;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
index ea3b3dc..2e94844 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
@@ -55,50 +55,103 @@
boolean hasSubstitution = substitution != null;
if (!(argumentType instanceof ReferenceBinding || argumentType.isArrayType()))
return TypeConstants.MISMATCH;
-
- if (argumentType.isWildcard()) {
- WildcardBinding wildcard = (WildcardBinding) argumentType;
- switch (wildcard.boundKind) {
- case Wildcard.SUPER :
-// if (boundCheck(substitution, wildcard.bound) != TypeConstants.OK) return TypeConstants.MISMATCH;
-// break;
- return boundCheck(substitution, wildcard.bound); // only check the lower bound
- case Wildcard.UNBOUND :
- if (this == wildcard.typeVariable())
+ // special case for re-entrant source types (selection, code assist, etc)...
+ // can request additional types during hierarchy walk that are found as source types that also 'need' to connect their hierarchy
+ if (this.superclass == null)
+ return TypeConstants.OK;
+
+ if (argumentType.isWildcard() && !argumentType.isIntersectionType()) {
+ WildcardBinding wildcard = (WildcardBinding) argumentType;
+ switch(wildcard.boundKind) {
+ case Wildcard.EXTENDS :
+ TypeBinding wildcardBound = wildcard.bound;
+ if (wildcardBound == this)
return TypeConstants.OK;
- break;
- }
- }
+ ReferenceBinding superclassBound = hasSubstitution ? (ReferenceBinding)Scope.substitute(substitution, this.superclass) : this.superclass;
+ boolean isArrayBound = wildcardBound.isArrayType();
+ if (!wildcardBound.isInterface()) {
+ if (superclassBound.id != T_JavaLangObject) {
+ if (isArrayBound) {
+ if (!wildcardBound.isCompatibleWith(superclassBound))
+ return TypeConstants.MISMATCH;
+ } else {
+ ReferenceBinding match = ((ReferenceBinding)wildcardBound).findSuperTypeWithSameErasure(superclassBound);
+ if (match != null) {
+ if (!match.isIntersectingWith(superclassBound)) {
+ return TypeConstants.MISMATCH;
+ }
+ } else {
+ return TypeConstants.MISMATCH;
+ }
+ }
+ }
+ }
+ ReferenceBinding[] superInterfaceBounds = hasSubstitution ? Scope.substitute(substitution, this.superInterfaces) : this.superInterfaces;
+ int length = superInterfaceBounds.length;
+ boolean mustImplement = isArrayBound || ((ReferenceBinding)wildcardBound).isFinal();
+ for (int i = 0; i < length; i++) {
+ TypeBinding superInterfaceBound = superInterfaceBounds[i];
+ if (isArrayBound) {
+ if (!wildcardBound.isCompatibleWith(superInterfaceBound))
+ return TypeConstants.MISMATCH;
+ } else {
+ ReferenceBinding match = ((ReferenceBinding)wildcardBound).findSuperTypeWithSameErasure(superInterfaceBound);
+ if (match != null) {
+ if (!match.isIntersectingWith(superInterfaceBound)) {
+ return TypeConstants.MISMATCH;
+ }
+ } else if (mustImplement) {
+ return TypeConstants.MISMATCH; // cannot be extended further to satisfy missing bounds
+ }
+ }
+
+ }
+ break;
+
+ case Wildcard.SUPER :
+ return boundCheck(substitution, wildcard.bound);
+
+ case Wildcard.UNBOUND :
+ break;
+ }
+ return TypeConstants.OK;
+ }
boolean unchecked = false;
if (this.superclass.id != T_JavaLangObject) {
- TypeBinding substitutedSuperType = hasSubstitution ? Scope.substitute(substitution, this.superclass) : this.superclass;
- if (!argumentType.isCompatibleWith(substitutedSuperType)) {
- return TypeConstants.MISMATCH;
- }
- if (argumentType instanceof ReferenceBinding) {
- ReferenceBinding referenceArgument = (ReferenceBinding) argumentType;
- TypeBinding match = referenceArgument.findSuperTypeErasingTo((ReferenceBinding)substitutedSuperType.erasure());
- if (match != null){
- // Enum#RAW is not a substitute for <E extends Enum<E>> (86838)
- if (match.isRawType() && (substitutedSuperType.isGenericType()||substitutedSuperType.isBoundParameterizedType()))
- unchecked = true;
+ TypeBinding superType = this.superclass;
+ if (superType != argumentType) { // check identity before substituting (104649)
+ TypeBinding substitutedSuperType = hasSubstitution ? Scope.substitute(substitution, superType) : superType;
+ if (!argumentType.isCompatibleWith(substitutedSuperType)) {
+ return TypeConstants.MISMATCH;
}
+ if (argumentType instanceof ReferenceBinding) {
+ ReferenceBinding referenceArgument = (ReferenceBinding) argumentType;
+ TypeBinding match = referenceArgument.findSuperTypeWithSameErasure(substitutedSuperType);
+ if (match != null){
+ // Enum#RAW is not a substitute for <E extends Enum<E>> (86838)
+ if (match.isRawType() && (substitutedSuperType.isGenericType()||substitutedSuperType.isBoundParameterizedType()))
+ unchecked = true;
+ }
+ }
}
}
for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
- TypeBinding substitutedSuperType = hasSubstitution ? Scope.substitute(substitution, this.superInterfaces[i]) : this.superInterfaces[i];
- if (!argumentType.isCompatibleWith(substitutedSuperType)) {
- return TypeConstants.MISMATCH;
- }
- if (argumentType instanceof ReferenceBinding) {
- ReferenceBinding referenceArgument = (ReferenceBinding) argumentType;
- TypeBinding match = referenceArgument.findSuperTypeErasingTo((ReferenceBinding)substitutedSuperType.erasure());
- if (match != null){
- // Enum#RAW is not a substitute for <E extends Enum<E>> (86838)
- if (match.isRawType() && (substitutedSuperType.isGenericType()||substitutedSuperType.isBoundParameterizedType()))
- unchecked = true;
+ TypeBinding superType = this.superInterfaces[i];
+ if (superType != argumentType) { // check identity before substituting (104649)
+ TypeBinding substitutedSuperType = hasSubstitution ? Scope.substitute(substitution, superType) : superType;
+ if (!argumentType.isCompatibleWith(substitutedSuperType)) {
+ return TypeConstants.MISMATCH;
}
- }
+ if (argumentType instanceof ReferenceBinding) {
+ ReferenceBinding referenceArgument = (ReferenceBinding) argumentType;
+ TypeBinding match = referenceArgument.findSuperTypeWithSameErasure(substitutedSuperType);
+ if (match != null){
+ // Enum#RAW is not a substitute for <E extends Enum<E>> (86838)
+ if (match.isRawType() && (substitutedSuperType.isGenericType()||substitutedSuperType.isBoundParameterizedType()))
+ unchecked = true;
+ }
+ }
+ }
}
return unchecked ? TypeConstants.UNCHECKED : TypeConstants.OK;
}
@@ -173,17 +226,34 @@
}
/*
* declaringUniqueKey : genericTypeSignature
- * p.X<T> { ... } --> Lp/X<TT;>;:TT;
+ * p.X<T> { ... } --> Lp/X;:TT;
+ * p.X { <T> void foo() {...} } --> Lp/X;.foo()V:TT;
*/
- public char[] computeUniqueKey(boolean withAccessFlags) {
- char[] declaringKey = this.declaringElement.computeUniqueKey(false/*without access flags*/);
- int declaringLength = declaringKey.length;
- char[] sig = genericTypeSignature();
- int sigLength = sig.length;
- char[] uniqueKey = new char[declaringLength + 1 + sigLength];
- System.arraycopy(declaringKey, 0, uniqueKey, 0, declaringLength);
- uniqueKey[declaringLength] = ':';
- System.arraycopy(sig, 0, uniqueKey, declaringLength+1, sigLength);
+ public char[] computeUniqueKey(boolean isLeaf) {
+ StringBuffer buffer = new StringBuffer();
+ Binding declaring = this.declaringElement;
+ if (!isLeaf && declaring.kind() == Binding.METHOD) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=97902
+ MethodBinding methodBinding = (MethodBinding) declaring;
+ ReferenceBinding declaringClass = methodBinding.declaringClass;
+ buffer.append(declaringClass.computeUniqueKey(false/*not a leaf*/));
+ buffer.append(':');
+ MethodBinding[] methods = declaringClass.methods();
+ if (methods != null)
+ for (int i = 0, length = methods.length; i < length; i++) {
+ MethodBinding binding = methods[i];
+ if (binding == methodBinding) {
+ buffer.append(i);
+ break;
+ }
+ }
+ } else {
+ buffer.append(declaring.computeUniqueKey(false/*not a leaf*/));
+ buffer.append(':');
+ }
+ buffer.append(genericTypeSignature());
+ int length = buffer.length();
+ char[] uniqueKey = new char[length];
+ buffer.getChars(0, length, uniqueKey, 0);
return uniqueKey;
}
/**
@@ -199,93 +269,6 @@
return this.superclass; // java/lang/Object
}
-/**
- * Find supertype which erases to a given well-known type, or null if not found
- * (using id avoids triggering the load of well-known type: 73740)
- * NOTE: only works for erasures of well-known types, as random other types may share
- * same id though being distincts.
- * Override super-method since erasure() is answering firstBound (first supertype) already
- */
-public ReferenceBinding findSuperTypeErasingTo(int erasureId, boolean erasureIsClass) {
-
-// if (this.id == erasureId) return this; // no ID for type variable
- ReferenceBinding currentType = this;
- // iterate superclass to avoid recording interfaces if searched supertype is class
- if (erasureIsClass) {
- while ((currentType = currentType.superclass()) != null) {
- if (currentType.id == erasureId || currentType.erasure().id == erasureId) return currentType;
- }
- return null;
- }
- ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
- int lastPosition = -1;
- do {
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
- } while ((currentType = currentType.superclass()) != null);
-
- for (int i = 0; i <= lastPosition; i++) {
- ReferenceBinding[] interfaces = interfacesToVisit[i];
- for (int j = 0, length = interfaces.length; j < length; j++) {
- if ((currentType = interfaces[j]).id == erasureId || currentType.erasure().id == erasureId)
- return currentType;
-
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
- }
- }
- return null;
-}
-/**
- * Find supertype which erases to a given type, or null if not found
- * Override super-method since erasure() is answering firstBound (first supertype) already
- */
-public ReferenceBinding findSuperTypeErasingTo(ReferenceBinding erasure) {
-
- if (this == erasure) return this;
- ReferenceBinding currentType = this;
- if (!erasure.isInterface()) {
- while ((currentType = currentType.superclass()) != null) {
- if (currentType == erasure || currentType.erasure() == erasure) return currentType;
- }
- return null;
- }
- ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
- int lastPosition = -1;
- do {
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
- } while ((currentType = currentType.superclass()) != null);
-
- for (int i = 0; i <= lastPosition; i++) {
- ReferenceBinding[] interfaces = interfacesToVisit[i];
- for (int j = 0, length = interfaces.length; j < length; j++) {
- if ((currentType = interfaces[j]) == erasure || currentType.erasure() == erasure)
- return currentType;
-
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != NoSuperInterfaces) {
- if (++lastPosition == interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
- interfacesToVisit[lastPosition] = itsInterfaces;
- }
- }
- }
- return null;
-}
-
/**
* T::Ljava/util/Map;:Ljava/io/Serializable;
* T:LY<TT;>
@@ -326,13 +309,57 @@
}
return false;
}
+
+ /**
+ * Returns true if the 2 variables are playing exact same role: they have
+ * the same bounds, providing one is substituted with the other: <T1 extends
+ * List<T1>> is interchangeable with <T2 extends List<T2>>.
+ */
+ public boolean isInterchangeableWith(final LookupEnvironment environment, final TypeVariableBinding otherVariable) {
+ if (this == otherVariable)
+ return true;
+ int length = this.superInterfaces.length;
+ if (length != otherVariable.superInterfaces.length)
+ return false;
+
+ identical: {
+ if (this.superclass != otherVariable.superclass) {
+ if (this.superclass.erasure() != otherVariable.superclass.erasure())
+ return false; // no way it can match after substitution
+ break identical;
+ }
+ for (int i = 0; i < length; i++) {
+ if (this.superInterfaces[i] != otherVariable.superInterfaces[i]) {
+ if (this.superInterfaces[i].erasure() != otherVariable.superInterfaces[i].erasure())
+ return false; // no way it can match after substitution
+ break identical;
+ }
+ }
+ return true;
+ }
+ // need substitutions
+ Substitution subst = new Substitution() {
+ public LookupEnvironment environment() { return environment; }
+ public boolean isRawSubstitution() { return false; }
+ public TypeBinding substitute(TypeVariableBinding typeVariable) {
+ return typeVariable == otherVariable ? TypeVariableBinding.this : typeVariable;
+ }
+ };
+ if (this.superclass != Scope.substitute(subst, otherVariable.superclass))
+ return false;
+ for (int i = 0; i < length; i++)
+ if (this.superInterfaces[i] != Scope.substitute(subst, otherVariable.superInterfaces[i]))
+ return false;
+ return true;
+ }
+
/**
* Returns true if the type was declared as a type variable
*/
public boolean isTypeVariable() {
return true;
}
-
+
/**
* Returns the original type variable for a given variable.
* Only different from receiver for type variables of generic methods of parameterized types
@@ -430,4 +457,13 @@
buffer.append('>');
return buffer.toString();
}
+ /**
+ * Upper bound doesn't perform erasure
+ */
+ public TypeBinding upperBound() {
+ if (this.firstBound != null) {
+ return this.firstBound;
+ }
+ return this.superclass; // java/lang/Object
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
index bef72ed..0cd1f6e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
@@ -49,17 +49,7 @@
}
}
if (convertGenericToRawType) {
- boolean rawEnclosing = false;
- ReferenceBinding targetEnclosingType = targetType.enclosingType();
- if (targetEnclosingType != null && targetEnclosingType.isGenericType()) { // convert to raw type since wasn't parameterized
- rawEnclosing = true;
- targetEnclosingType = environment.createRawType(targetEnclosingType, targetEnclosingType.enclosingType());
- }
- if (targetType.isGenericType()) { // raw reference to generic ?
- return environment.createRawType(targetType, targetEnclosingType);
- } else if (rawEnclosing) {
- return environment.createParameterizedType(targetType, null, targetEnclosingType);
- }
+ targetType = (ReferenceBinding) environment.convertToRawType(targetType);
}
return targetType;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
index eeb487c..3e60bd7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
@@ -80,6 +80,7 @@
// cannot be asked per construction
return false;
}
+
/**
* Collect the substitutes into a map for certain type variables inside the receiver type
* e.g. Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
@@ -262,15 +263,25 @@
}
}
- public char[] computeUniqueKey(boolean withAccessFlags) {
+ /*
+ * genericTypeKey *|+|- [boundKey]
+ * p.X<T> { X<?> ... } --> Lp/X<TT;>;*
+ */
+ public char[] computeUniqueKey(boolean isLeaf) {
+ char[] genericTypeKey = this.genericType.computeUniqueKey(false/*not a leaf*/);
+ char[] wildCardKey;
switch (this.boundKind) {
case Wildcard.UNBOUND :
- return WILDCARD_STAR;
+ wildCardKey = WILDCARD_STAR;
+ break;
case Wildcard.EXTENDS :
- return CharOperation.concat(WILDCARD_PLUS, this.bound.computeUniqueKey(false/*without access flags*/));
+ wildCardKey = CharOperation.concat(WILDCARD_PLUS, this.bound.computeUniqueKey(false/*not a leaf*/));
+ break;
default: // SUPER
- return CharOperation.concat(WILDCARD_MINUS, this.bound.computeUniqueKey(false/*without access flags*/));
+ wildCardKey = CharOperation.concat(WILDCARD_MINUS, this.bound.computeUniqueKey(false/*not a leaf*/));
+ break;
}
+ return CharOperation.concat(genericTypeKey, wildCardKey);
}
/**
@@ -320,8 +331,7 @@
this.fPackage = someGenericType.getPackage();
}
if (someBound != null) {
- if (someBound.isTypeVariable())
- this.tagBits |= HasTypeVariable;
+ this.tagBits |= someBound.tagBits & HasTypeVariable;
}
}
@@ -338,7 +348,14 @@
}
return false;
}
-
+
+ /**
+ * Returns true if the current type denotes an intersection type: Number & Comparable<?>
+ */
+ public boolean isIntersectionType() {
+ return this.otherBounds != null;
+ }
+
/**
* Returns true if the type is a wildcard
*/
@@ -467,6 +484,30 @@
return this.superclass;
}
+
+ public ReferenceBinding superclass2() {
+ if (this.superclass == null) {
+ TypeBinding superType = (this.boundKind == Wildcard.EXTENDS && !this.bound.isInterface())
+ ? this.bound
+ : null;
+ this.superclass = superType instanceof ReferenceBinding && !superType.isInterface()
+ ? (ReferenceBinding) superType
+ : environment.getType(JAVA_LANG_OBJECT);
+
+// TypeBinding superType = null;
+// if (this.boundKind == Wildcard.EXTENDS && !this.bound.isInterface()) {
+// superType = this.bound;
+// } else {
+// TypeVariableBinding variable = this.typeVariable();
+// if (variable != null) superType = variable.firstBound;
+// }
+// this.superclass = superType instanceof ReferenceBinding && !superType.isInterface()
+// ? (ReferenceBinding) superType
+// : environment.getType(JAVA_LANG_OBJECT);
+ }
+
+ return this.superclass;
+ }
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#superInterfaces()
*/
@@ -498,13 +539,38 @@
return this.superInterfaces;
}
+ public ReferenceBinding[] superInterfaces2() {
+ if (this.superInterfaces == null) {
+ if (this.boundKind == Wildcard.EXTENDS) {
+ if (this.bound.isInterface()) {
+ if (this.otherBounds != null) {
+ // augment super interfaces with the wildcard otherBounds (interfaces per construction)
+ int otherLength = this.otherBounds.length;
+ System.arraycopy(this.otherBounds, 0, this.superInterfaces = new ReferenceBinding[otherLength+1], 1, otherLength);
+ this.superInterfaces[0] = (ReferenceBinding) this.bound;
+ } else {
+ this.superInterfaces = new ReferenceBinding[] { (ReferenceBinding) this.bound };
+ }
+ } else if (this.otherBounds != null) {
+ int otherLength = this.otherBounds.length;
+ System.arraycopy(this.otherBounds, 0, this.superInterfaces = new ReferenceBinding[otherLength], 0, otherLength);
+ } else {
+ this.superInterfaces = NoSuperInterfaces;
+ }
+ } else {
+ this.superInterfaces = NoSuperInterfaces;
+ }
+ }
+ return this.superInterfaces;
+ }
+
public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
boolean affected = false;
if (this.genericType == unresolvedType) {
this.genericType = resolvedType; // no raw conversion
affected = true;
} else if (this.bound == unresolvedType) {
- this.bound = resolvedType.isGenericType() ? env.createRawType(resolvedType, resolvedType.enclosingType()) : resolvedType;
+ this.bound = env.convertToRawType(resolvedType);
affected = true;
}
if (affected)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/messages.properties
similarity index 100%
rename from org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/messages.properties
rename to org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/messages.properties
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
index e1a39ff..b411ffa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
@@ -853,7 +853,7 @@
// Report problem
this.currentTokenType = -1;
end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
- while (readToken() != TerminalTokens.TokenNameWHITESPACE) {
+ while ((token=readToken()) != TerminalTokens.TokenNameWHITESPACE && token != TerminalTokens.TokenNameEOF) {
this.currentTokenType = -1;
end = hasMultiLines ? this.lineEnd: this.scanner.getCurrentTokenEndPosition();
}
@@ -883,7 +883,7 @@
// Scan tokens
int primitiveToken = -1;
nextToken : for (int iToken = 0; ; iToken++) {
- int token = readToken();
+ int token = readTokenSafely();
switch (token) {
case TerminalTokens.TokenNameIdentifier :
if (((iToken % 2) > 0)) { // identifiers must be odd tokens
@@ -957,9 +957,10 @@
// Get reference tokens
nextToken : while (this.index < this.scanner.eofPosition) {
previousPosition = this.index;
- int token = readToken();
+ int token = readTokenSafely();
switch (token) {
- case TerminalTokens.TokenNameStringLiteral : // @see "string"
+ case TerminalTokens.TokenNameStringLiteral : // @see "string"
+ if (typeRef != null) break nextToken;
consumeToken();
int start = this.scanner.getCurrentTokenStartPosition();
if (this.tagValue == TAG_VALUE_VALUE) {
@@ -981,6 +982,7 @@
if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedText(this.scanner.currentPosition, this.lineEnd);
return false;
case TerminalTokens.TokenNameLESS : // @see "<a href="URL#Value">label</a>
+ if (typeRef != null) break nextToken;
consumeToken();
start = this.scanner.getCurrentTokenStartPosition();
if (parseHref()) {
@@ -1014,6 +1016,11 @@
}
return false;
}
+ char[] currentError = this.scanner.getCurrentIdentifierSource();
+ if (currentError.length>0 && currentError[0] == '"') {
+ if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidReference(this.scanner.getCurrentTokenStartPosition(), getTokenEndPosition());
+ return false;
+ }
break nextToken;
case TerminalTokens.TokenNameIdentifier :
if (typeRef == null) {
@@ -1270,6 +1277,21 @@
consumeToken();
return token;
}
+
+ /*
+ * Read token without throwing any InvalidInputException exception.
+ * Returns TerminalTokens.TokenNameERROR instead.
+ */
+ protected int readTokenSafely() {
+ int token = TerminalTokens.TokenNameERROR;
+ try {
+ token = readToken();
+ }
+ catch (InvalidInputException iie) {
+ // token is already set to error
+ }
+ return token;
+ }
/*
* Refresh start position and length of an inline tag.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
index e6e3388..18cf1c8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
@@ -318,6 +318,54 @@
case TerminalTokens.TokenNameIdentifier:
case TerminalTokens.TokenNamereturn:
case TerminalTokens.TokenNamethrows:
+ case TerminalTokens.TokenNameabstract:
+ case TerminalTokens.TokenNameassert:
+ case TerminalTokens.TokenNameboolean:
+ case TerminalTokens.TokenNamebreak:
+ case TerminalTokens.TokenNamebyte:
+ case TerminalTokens.TokenNamecase:
+ case TerminalTokens.TokenNamecatch:
+ case TerminalTokens.TokenNamechar:
+ case TerminalTokens.TokenNameclass:
+ case TerminalTokens.TokenNamecontinue:
+ case TerminalTokens.TokenNamedefault:
+ case TerminalTokens.TokenNamedo:
+ case TerminalTokens.TokenNamedouble:
+ case TerminalTokens.TokenNameelse:
+ case TerminalTokens.TokenNameextends:
+ case TerminalTokens.TokenNamefalse:
+ case TerminalTokens.TokenNamefinal:
+ case TerminalTokens.TokenNamefinally:
+ case TerminalTokens.TokenNamefloat:
+ case TerminalTokens.TokenNamefor:
+ case TerminalTokens.TokenNameif:
+ case TerminalTokens.TokenNameimplements:
+ case TerminalTokens.TokenNameimport:
+ case TerminalTokens.TokenNameinstanceof:
+ case TerminalTokens.TokenNameint:
+ case TerminalTokens.TokenNameinterface:
+ case TerminalTokens.TokenNamelong:
+ case TerminalTokens.TokenNamenative:
+ case TerminalTokens.TokenNamenew:
+ case TerminalTokens.TokenNamenull:
+ case TerminalTokens.TokenNamepackage:
+ case TerminalTokens.TokenNameprivate:
+ case TerminalTokens.TokenNameprotected:
+ case TerminalTokens.TokenNamepublic:
+ case TerminalTokens.TokenNameshort:
+ case TerminalTokens.TokenNamestatic:
+ case TerminalTokens.TokenNamestrictfp:
+ case TerminalTokens.TokenNamesuper:
+ case TerminalTokens.TokenNameswitch:
+ case TerminalTokens.TokenNamesynchronized:
+ case TerminalTokens.TokenNamethis:
+ case TerminalTokens.TokenNamethrow:
+ case TerminalTokens.TokenNametransient:
+ case TerminalTokens.TokenNametrue:
+ case TerminalTokens.TokenNametry:
+ case TerminalTokens.TokenNamevoid:
+ case TerminalTokens.TokenNamevolatile:
+ case TerminalTokens.TokenNamewhile:
validTag= true;
}
tagNameToken: while (token != TerminalTokens.TokenNameEOF && this.index < this.scanner.eofPosition) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index 626e32a..770b5ee 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -703,6 +703,11 @@
// javadoc support
this.javadocParser = new JavadocParser(this);
}
+protected void annotationRecoveryCheckPoint(int start, int end) {
+ if(this.lastCheckPoint > start && this.lastCheckPoint < end) {
+ this.lastCheckPoint = end + 1;
+ }
+}
public void arrayInitializer(int length) {
//length is the size of the array Initializer
//expressionPtr points on the last elt of the arrayInitializer,
@@ -1037,7 +1042,11 @@
}
}
protected void consumeAnnotationName() {
- // nothing to do
+ if(this.currentElement != null) {
+ int start = this.intStack[this.intPtr];
+ int end = (int) (this.identifierPositionStack[this.identifierPtr] & 0x00000000FFFFFFFFL);
+ annotationRecoveryCheckPoint(start, end);
+ }
}
protected void consumeAnnotationTypeDeclaration() {
int length;
@@ -1070,6 +1079,8 @@
if (this.currentElement != null) {
this.restartRecovery = true; // used to avoid branching back into the regular automaton
}
+ // flush the comments related to the annotation type header
+ this.scanner.commentPtr = -1;
}
protected void consumeAnnotationTypeDeclarationHeaderName() {
// consumeAnnotationTypeDeclarationHeader ::= Modifiers '@' PushModifiers interface Identifier
@@ -1245,7 +1256,8 @@
arrayInitializer(this.expressionLengthStack[this.expressionLengthPtr--]);
}
protected void consumeArrayTypeWithTypeArgumentsName() {
- this.intStack[this.intPtr] += this.identifierLengthStack[this.identifierLengthPtr];
+ this.genericsIdentifiersLengthStack[this.genericsIdentifiersLengthPtr] += this.identifierLengthStack[this.identifierLengthPtr];
+ pushOnGenericsLengthStack(0); // handle type arguments
}
protected void consumeAssertStatement() {
// AssertStatement ::= 'assert' Expression ':' Expression ';'
@@ -1733,6 +1745,9 @@
// ClassBodyDeclarationsopt ::= NestedType ClassBodyDeclarations
this.nestedType-- ;
}
+protected void consumeAnnotationTypeMemberDeclarationsopt() {
+ this.nestedType-- ;
+}
protected void consumeClassBodyopt() {
// ClassBodyopt ::= $empty
pushOnAstStack(null);
@@ -2575,6 +2590,10 @@
anonymousType.bodyStart = this.scanner.currentPosition;
this.listLength = 0; // will be updated when reading super-interfaces
+
+ // flush the comments related to the anonymous
+ this.scanner.commentPtr = -1;
+
// recovery
if (this.currentElement != null){
this.lastCheckPoint = anonymousType.bodyStart;
@@ -3128,10 +3147,9 @@
pushOnExpressionStack(fr);
} else {
//optimize push/pop
- if ((fr.receiver = this.expressionStack[this.expressionPtr]).isThis()) {
- //fieldreference begins at the this
- fr.sourceStart = fr.receiver.sourceStart;
- }
+ fr.receiver = this.expressionStack[this.expressionPtr];
+ //fieldreference begins at the receiver
+ fr.sourceStart = fr.receiver.sourceStart;
this.expressionStack[this.expressionPtr] = fr;
}
}
@@ -3280,7 +3298,8 @@
// Will be consume by a getTypeRefence call
}
protected void consumeGenericTypeNameArrayType() {
- pushOnGenericsLengthStack(0); // handle type arguments
+ // nothing to do
+ // Will be consume by a getTypeRefence call
}
protected void consumeImportDeclaration() {
// SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
@@ -4189,6 +4208,11 @@
}
normalAnnotation.declarationSourceEnd = this.rParenPos;
pushOnExpressionStack(normalAnnotation);
+
+ if(this.currentElement != null) {
+ annotationRecoveryCheckPoint(normalAnnotation.sourceStart, normalAnnotation.declarationSourceEnd);
+ }
+
if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
this.problemReporter().invalidUsageOfAnnotation(normalAnnotation);
@@ -4230,7 +4254,11 @@
this.realBlockStack[this.realBlockPtr] = 0;
}
protected void consumePackageComment() {
- // do nothing
+ // get possible comment for syntax since 1.5
+ if(options.sourceLevel >= ClassFileConstants.JDK1_5) {
+ checkComment();
+ resetModifiers();
+ }
}
protected void consumePackageDeclaration() {
// PackageDeclaration ::= 'package' Name ';'
@@ -4238,6 +4266,8 @@
stored in the identifier stack. */
ImportReference impt = this.compilationUnit.currentPackage;
+ this.compilationUnit.javadoc = this.javadoc;
+ this.javadoc = null;
// flush comments defined prior to import statements
impt.declarationEnd = this.endStatementPosition;
impt.declarationSourceEnd = this.flushCommentsDefinedPriorTo(impt.declarationSourceEnd);
@@ -4273,6 +4303,11 @@
//this.endPosition is just before the ;
impt.declarationSourceStart = this.intStack[this.intPtr--];
+ // get possible comment source start
+ if(this.javadoc != null) {
+ impt.declarationSourceStart = this.javadoc.sourceStart;
+ }
+
// recovery
if (this.currentElement != null){
this.lastCheckPoint = impt.declarationSourceEnd+1;
@@ -4315,6 +4350,10 @@
intPtr--; // we don't need the position of the 'package keyword
} else {
impt.declarationSourceStart = this.intStack[this.intPtr--];
+ // get possible comment source start
+ if (this.javadoc != null) {
+ impt.declarationSourceStart = this.javadoc.sourceStart;
+ }
}
if (this.currentToken == TokenNameSEMICOLON){
@@ -6050,6 +6089,10 @@
consumeEmptyAnnotationTypeMemberDeclarationsopt() ;
break;
+ case 651 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$
+ consumeAnnotationTypeMemberDeclarationsopt() ;
+ break;
+
case 653 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); } //$NON-NLS-1$
consumeAnnotationTypeMemberDeclarations() ;
break;
@@ -6170,6 +6213,12 @@
this.expressionLengthPtr--;
singleMemberAnnotation.declarationSourceEnd = this.rParenPos;
pushOnExpressionStack(singleMemberAnnotation);
+
+
+ if(this.currentElement != null) {
+ annotationRecoveryCheckPoint(singleMemberAnnotation.sourceStart, singleMemberAnnotation.declarationSourceEnd);
+ }
+
if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
this.problemReporter().invalidUsageOfAnnotation(singleMemberAnnotation);
@@ -6878,11 +6927,12 @@
this.endPosition = this.scanner.startPosition;
this.endStatementPosition = this.scanner.currentPosition - 1;
break;
+ case TokenNameLBRACE :
+ this.endStatementPosition = this.scanner.currentPosition - 1;
case TokenNamePLUS :
case TokenNameMINUS :
case TokenNameNOT :
case TokenNameTWIDDLE :
- case TokenNameLBRACE :
this.endPosition = this.scanner.startPosition;
break;
case TokenNamePLUS_PLUS :
@@ -8040,7 +8090,7 @@
this.scanner.recordLineSeparator = false;
}
public void goForMemberValue() {
- //tells the scanner to go for a memeber value parsing
+ //tells the scanner to go for a member value parsing
this.firstToken = TokenNameOR_OR;
this.scanner.recordLineSeparator = true; // recovery goals must record line separators
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
index b277b64..01bf9a2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
@@ -16,20 +16,20 @@
int ERROR_SYMBOL = 110,
MAX_NAME_LENGTH = 41,
- NUM_STATES = 953,
+ NUM_STATES = 955,
NT_OFFSET = 110,
SCOPE_UBOUND = 131,
SCOPE_SIZE = 132,
- LA_STATE_OFFSET = 12568,
+ LA_STATE_OFFSET = 12619,
MAX_LA = 1,
NUM_RULES = 691,
NUM_TERMINALS = 110,
NUM_NON_TERMINALS = 306,
NUM_SYMBOLS = 416,
- START_STATE = 1045,
+ START_STATE = 1466,
EOFT_SYMBOL = 66,
EOLT_SYMBOL = 66,
- ACCEPT_ACTION = 12567,
- ERROR_ACTION = 12568;
+ ACCEPT_ACTION = 12618,
+ ERROR_ACTION = 12619;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
index 91f1751..867857e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
@@ -133,9 +133,7 @@
typeDeclaration.declarationSourceEnd = this.fieldDeclaration.declarationSourceEnd;
typeDeclaration.bodyEnd = this.fieldDeclaration.declarationSourceEnd;
}
- if (recoveredType.preserveContent){
- recoveredType.updatedTypeDeclaration();
- }
+ recoveredType.updatedTypeDeclaration();
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java
index 193ac00..12c96d4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java
@@ -318,8 +318,8 @@
* is about to disappear because of restarting recovery
*/
public void updateFromParserState(){
-
- if(this.bodyStartsAtHeaderEnd()){
+ // if parent is null then recovery already occured in diet parser.
+ if(this.bodyStartsAtHeaderEnd() && this.parent != null){
Parser parser = this.parser();
/* might want to recover arguments or thrown exceptions */
if (parser.listLength > 0 && parser.astLengthPtr > 0){ // awaiting interface type references
@@ -375,19 +375,28 @@
// to compute bodyStart, and thus used to set next checkpoint.
int count;
for (count = 0; count < argLength; count++){
- Argument argument = (Argument)parser.astStack[argStart+count];
- /* cannot be an argument if non final */
- char[][] argTypeName = argument.type.getTypeName();
- if ((argument.modifiers & ~AccFinal) != 0
- || (argTypeName.length == 1
- && CharOperation.equals(argTypeName[0], VoidBinding.sourceName()))){
+ ASTNode aNode = parser.astStack[argStart+count];
+ if(aNode instanceof Argument) {
+ Argument argument = (Argument)aNode;
+ /* cannot be an argument if non final */
+ char[][] argTypeName = argument.type.getTypeName();
+ if ((argument.modifiers & ~AccFinal) != 0
+ || (argTypeName.length == 1
+ && CharOperation.equals(argTypeName[0], VoidBinding.sourceName()))){
+ parser.astLengthStack[parser.astLengthPtr] = count;
+ parser.astPtr = argStart+count-1;
+ parser.listLength = count;
+ parser.currentToken = 0;
+ break;
+ }
+ if (needUpdateRParenPos) parser.rParenPos = argument.sourceEnd + 1;
+ } else {
parser.astLengthStack[parser.astLengthPtr] = count;
parser.astPtr = argStart+count-1;
parser.listLength = count;
parser.currentToken = 0;
break;
}
- if (needUpdateRParenPos) parser.rParenPos = argument.sourceEnd + 1;
}
if (parser.listLength > 0 && parser.astLengthPtr > 0){
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java
index 15c475b..0be747a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java
@@ -45,7 +45,12 @@
public RecoveredType(TypeDeclaration typeDeclaration, RecoveredElement parent, int bracketBalance){
super(typeDeclaration, parent, bracketBalance);
this.typeDeclaration = typeDeclaration;
- this.foundOpeningBrace = !bodyStartsAtHeaderEnd();
+ if(typeDeclaration.allocation != null && typeDeclaration.allocation.type == null) {
+ // an enum constant body can not exist if there is no opening brace
+ this.foundOpeningBrace = true;
+ } else {
+ this.foundOpeningBrace = !bodyStartsAtHeaderEnd();
+ }
this.insideEnumConstantPart = typeDeclaration.kind() == IGenericType.ENUM_DECL;
if(this.foundOpeningBrace) {
this.bracketBalance++;
@@ -414,7 +419,8 @@
*/
public void updateFromParserState(){
- if(this.bodyStartsAtHeaderEnd()){
+ // anymous type and enum constant doesn't need to be updated
+ if(this.bodyStartsAtHeaderEnd() && typeDeclaration.allocation == null){
Parser parser = this.parser();
/* might want to recover implemented interfaces */
// protection for bugs 15142
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index feb4892..97b1754 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -908,6 +908,8 @@
if (this.currentPosition > this.eofPosition)
return TokenNameEOF;
}
+ if (this.currentPosition > this.eofPosition)
+ return TokenNameEOF;
if (checkIfUnicode) {
isWhiteSpace = jumpOverUnicodeWhiteSpace();
offset = this.currentPosition - offset;
@@ -956,12 +958,7 @@
this.withoutUnicodePtr = 0;
}
}
- //little trick to get out in the middle of a source compuation
- if (this.currentPosition > this.eofPosition)
- return TokenNameEOF;
-
// ---------Identify the next token-------------
-
switch (this.currentCharacter) {
case '@' :
/* if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
@@ -2388,11 +2385,6 @@
}
this.commentPtr = -1; // reset comment stack
this.foundTaskCount = 0;
-
-// // if resetTo is used with being > than end.
-// if (begin > this.eofPosition) {
-// begin = this.eofPosition;
-// }
}
public final void scanEscapeCharacter() throws InvalidInputException {
@@ -3359,20 +3351,30 @@
this.containsAssertKeyword = false;
this.linePtr = -1;
}
-
/*
* Should be used if a parse (usually a diet parse) has already been performed on the unit,
* so as to get the already computed line end positions.
*/
-public final void setSource(CompilationResult compilationResult) {
- char[] contents = compilationResult.compilationUnit.getContents();
- setSource(contents);
+public final void setSource(char[] contents, CompilationResult compilationResult) {
+ if (contents == null) {
+ char[] cuContents = compilationResult.compilationUnit.getContents();
+ setSource(cuContents);
+ } else {
+ setSource(contents);
+ }
int[] lineSeparatorPositions = compilationResult.lineSeparatorPositions;
if (lineSeparatorPositions != null) {
this.lineEnds = lineSeparatorPositions;
this.linePtr = lineSeparatorPositions.length - 1;
}
}
+/*
+ * Should be used if a parse (usually a diet parse) has already been performed on the unit,
+ * so as to get the already computed line end positions.
+ */
+public final void setSource(CompilationResult compilationResult) {
+ setSource(null, compilationResult);
+}
public String toString() {
if (this.startPosition == this.source.length)
return "EOF\n\n" + new String(this.source); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
index f161000..df8f7da 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
@@ -51,7 +51,7 @@
TokenNameelse = 103,
TokenNameenum = 98,
TokenNameextends = 99,
- TokenNamefalse = 45,
+ TokenNamefalse = 44,
TokenNamefinal = 57,
TokenNamefinally = 104,
TokenNamefloat = 36,
@@ -66,7 +66,7 @@
TokenNamelong = 38,
TokenNamenative = 58,
TokenNamenew = 43,
- TokenNamenull = 46,
+ TokenNamenull = 45,
TokenNamepackage = 96,
TokenNameprivate = 59,
TokenNameprotected = 60,
@@ -82,17 +82,17 @@
TokenNamethrow = 82,
TokenNamethrows = 105,
TokenNametransient = 63,
- TokenNametrue = 47,
+ TokenNametrue = 46,
TokenNametry = 83,
TokenNamevoid = 40,
TokenNamevolatile = 64,
TokenNamewhile = 73,
- TokenNameIntegerLiteral = 48,
- TokenNameLongLiteral = 49,
- TokenNameFloatingPointLiteral = 50,
- TokenNameDoubleLiteral = 51,
- TokenNameCharacterLiteral = 52,
- TokenNameStringLiteral = 53,
+ TokenNameIntegerLiteral = 47,
+ TokenNameLongLiteral = 48,
+ TokenNameFloatingPointLiteral = 49,
+ TokenNameDoubleLiteral = 50,
+ TokenNameCharacterLiteral = 51,
+ TokenNameStringLiteral = 52,
TokenNamePLUS_PLUS = 10,
TokenNameMINUS_MINUS = 11,
TokenNameEQUAL_EQUAL = 18,
@@ -139,7 +139,7 @@
TokenNameCOMMA = 30,
TokenNameDOT = 3,
TokenNameEQUAL = 71,
- TokenNameAT = 44,
+ TokenNameAT = 53,
TokenNameELLIPSIS = 107,
TokenNameEOF = 66,
TokenNameERROR = 110;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
index f08b9bf..12d3ef8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
index cf0228a..cf2a204 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
index 35baf52..6438e80 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
index d62f283..9dccdac 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
index 9a18dbc..92f5d61 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
index 5e93598..79a6cb6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
index 1365bda..0969339 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
index 856d1a0..dcdc0b5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
index 927a29e..fb9d761 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
@@ -1 +1 @@
-ggFFFEEhAAA!FfAeAIE JJE!EEbGG_!H!!!!!,
\ No newline at end of file
+ggFFFEEhAAA!FfAeAIE JJE!EEbGG_!H!!!!!5
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
index f088262..81f119f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
index 920127b..5cd9763 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
index d383385..d484da8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
index 355084e..baae381 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
index 0000f7c..ad2c407 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
index c79761e..eef9e8f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
index 5379910..4404e1b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
index 4a50e3d..7ebae37 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 849818e..fc509f1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -24,6 +24,14 @@
import org.eclipse.jdt.internal.compiler.util.Messages;
public class ProblemReporter extends ProblemHandler implements ProblemReasons {
+
+ /** These constants will be defined on IProblem in 3.2 branch, but are only internal in 3.1 maintenance
+ * stream so as not to compromise source compatibility with 3.1.0.
+ */
+ /** @since 3.2 */
+ private final static int JavadocNonStaticTypeFromStaticInvocation = IProblem.Javadoc + IProblem.Internal + 468;
+ /** @since 3.2 */
+ private final static int EnumStaticFieldInInInitializerContext = IProblem.FieldRelated + 762;
public ReferenceContext referenceContext;
@@ -314,14 +322,6 @@
location.sourceStart,
location.sourceEnd);
}
-public void boundHasConflictingArguments(ASTNode location, TypeBinding type) {
- this.handle(
- IProblem.BoundHasConflictingArguments,
- new String[] {new String(type.readableName())},
- new String[] {new String(type.shortReadableName())},
- location.sourceStart,
- location.sourceEnd);
-}
public void boundMustBeAnInterface(ASTNode location, TypeBinding type) {
this.handle(
IProblem.BoundMustBeAnInterface,
@@ -376,8 +376,8 @@
new String[] {
(field.declaringClass == null ? "array" : new String(field.declaringClass.shortReadableName())), //$NON-NLS-1$
new String(field.shortReadableName())},
- location.sourceStart,
- location.sourceEnd);
+ fieldSourceStart(field, location),
+ fieldSourceEnd(field, location));
}
public void cannotAssignToFinalLocal(LocalVariableBinding local, ASTNode location) {
String[] arguments = new String[] { new String(local.readableName())};
@@ -489,13 +489,13 @@
exceptionType.sourceStart,
exceptionType.sourceEnd);
}
-public void cannotUseQualifiedEnumConstantInCaseLabel(Reference reference, FieldBinding field) {
+public void cannotUseQualifiedEnumConstantInCaseLabel(Reference location, FieldBinding field) {
this.handle(
IProblem.IllegalQualifiedEnumConstantLabel,
new String[]{ String.valueOf(field.declaringClass.readableName()), String.valueOf(field.name) },
new String[]{ String.valueOf(field.declaringClass.shortReadableName()), String.valueOf(field.name) },
- reference.sourceStart,
- reference.sourceEnd);
+ fieldSourceStart(field, location),
+ fieldSourceEnd(field, location));
}
public void cannotUseSuperInCodeSnippet(int start, int end) {
this.handle(
@@ -559,197 +559,13 @@
* falls into:
* Error | Warning | Ignore
*/
-public int computeSeverity(int problemId){
+public int computeSeverity(int problemID){
- // severity can have been preset on the problem
-// if ((problem.severity & Fatal) != 0){
-// return Error;
-// }
-
- // if not then check whether it is a configurable problem
- switch(problemId){
-
- case IProblem.MaskedCatch :
- return this.options.getSeverity(CompilerOptions.MaskedCatchBlock);
-
- case IProblem.UnusedImport :
- return this.options.getSeverity(CompilerOptions.UnusedImport);
-
- case IProblem.MethodButWithConstructorName :
- return this.options.getSeverity(CompilerOptions.MethodWithConstructorName);
-
- case IProblem.OverridingNonVisibleMethod :
- return this.options.getSeverity(CompilerOptions.OverriddenPackageDefaultMethod);
-
- case IProblem.IncompatibleReturnTypeForNonInheritedInterfaceMethod :
- case IProblem.IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod :
- return this.options.getSeverity(CompilerOptions.IncompatibleNonInheritedInterfaceMethod);
-
- case IProblem.OverridingDeprecatedMethod :
- case IProblem.UsingDeprecatedType :
- case IProblem.UsingDeprecatedMethod :
- case IProblem.UsingDeprecatedConstructor :
- case IProblem.UsingDeprecatedField :
- return this.options.getSeverity(CompilerOptions.UsingDeprecatedAPI);
-
- case IProblem.LocalVariableIsNeverUsed :
- return this.options.getSeverity(CompilerOptions.UnusedLocalVariable);
-
- case IProblem.ArgumentIsNeverUsed :
- return this.options.getSeverity(CompilerOptions.UnusedArgument);
-
- case IProblem.NoImplicitStringConversionForCharArrayExpression :
- return this.options.getSeverity(CompilerOptions.NoImplicitStringConversion);
-
- case IProblem.NeedToEmulateFieldReadAccess :
- case IProblem.NeedToEmulateFieldWriteAccess :
- case IProblem.NeedToEmulateMethodAccess :
- case IProblem.NeedToEmulateConstructorAccess :
- return this.options.getSeverity(CompilerOptions.AccessEmulation);
-
- case IProblem.NonExternalizedStringLiteral :
- return this.options.getSeverity(CompilerOptions.NonExternalizedString);
-
- case IProblem.UseAssertAsAnIdentifier :
- return this.options.getSeverity(CompilerOptions.AssertUsedAsAnIdentifier);
- case IProblem.UseEnumAsAnIdentifier :
- return this.options.getSeverity(CompilerOptions.EnumUsedAsAnIdentifier);
-
- case IProblem.NonStaticAccessToStaticMethod :
- case IProblem.NonStaticAccessToStaticField :
- return this.options.getSeverity(CompilerOptions.NonStaticAccessToStatic);
-
- case IProblem.IndirectAccessToStaticMethod :
- case IProblem.IndirectAccessToStaticField :
- case IProblem.IndirectAccessToStaticType :
- return this.options.getSeverity(CompilerOptions.IndirectStaticAccess);
-
- case IProblem.AssignmentHasNoEffect:
- return this.options.getSeverity(CompilerOptions.NoEffectAssignment);
-
- case IProblem.UnusedPrivateConstructor:
- case IProblem.UnusedPrivateMethod:
- case IProblem.UnusedPrivateField:
- case IProblem.UnusedPrivateType:
- return this.options.getSeverity(CompilerOptions.UnusedPrivateMember);
-
+ switch (problemID) {
case IProblem.Task :
- return Warning;
-
- case IProblem.LocalVariableHidingLocalVariable:
- case IProblem.LocalVariableHidingField:
- case IProblem.ArgumentHidingLocalVariable:
- case IProblem.ArgumentHidingField:
- return this.options.getSeverity(CompilerOptions.LocalVariableHiding);
-
- case IProblem.FieldHidingLocalVariable:
- case IProblem.FieldHidingField:
- return this.options.getSeverity(CompilerOptions.FieldHiding);
-
- case IProblem.TypeParameterHidingType:
- return this.options.getSeverity(CompilerOptions.TypeParameterHiding);
+ case IProblem.VarargsConflict :
+ return ProblemSeverities.Warning;
- case IProblem.PossibleAccidentalBooleanAssignment:
- return this.options.getSeverity(CompilerOptions.AccidentalBooleanAssign);
-
- case IProblem.SuperfluousSemicolon:
- case IProblem.EmptyControlFlowStatement:
- return this.options.getSeverity(CompilerOptions.EmptyStatement);
-
- case IProblem.UndocumentedEmptyBlock:
- return this.options.getSeverity(CompilerOptions.UndocumentedEmptyBlock);
-
- case IProblem.UnnecessaryCast:
- case IProblem.UnnecessaryInstanceof:
- return this.options.getSeverity(CompilerOptions.UnnecessaryTypeCheck);
-
- case IProblem.FinallyMustCompleteNormally:
- return this.options.getSeverity(CompilerOptions.FinallyBlockNotCompleting);
-
- case IProblem.UnusedMethodDeclaredThrownException:
- case IProblem.UnusedConstructorDeclaredThrownException:
- return this.options.getSeverity(CompilerOptions.UnusedDeclaredThrownException);
-
- case IProblem.UnqualifiedFieldAccess:
- return this.options.getSeverity(CompilerOptions.UnqualifiedFieldAccess);
-
- case IProblem.UnnecessaryElse:
- return this.options.getSeverity(CompilerOptions.UnnecessaryElse);
-
- case IProblem.UnsafeRawConstructorInvocation:
- case IProblem.UnsafeRawMethodInvocation:
- case IProblem.UnsafeTypeConversion:
- case IProblem.UnsafeRawFieldAssignment:
- case IProblem.UnsafeGenericCast:
- case IProblem.UnsafeReturnTypeOverride:
- case IProblem.UnsafeRawGenericMethodInvocation:
- case IProblem.UnsafeRawGenericConstructorInvocation:
- return this.options.getSeverity(CompilerOptions.UncheckedTypeOperation);
-
- case IProblem.MissingOverrideAnnotation:
- return this.options.getSeverity(CompilerOptions.MissingOverrideAnnotation);
-
- case IProblem.FieldMissingDeprecatedAnnotation:
- case IProblem.MethodMissingDeprecatedAnnotation:
- case IProblem.TypeMissingDeprecatedAnnotation:
- return this.options.getSeverity(CompilerOptions.MissingDeprecatedAnnotation);
-
- case IProblem.FinalBoundForTypeVariable:
- return this.options.getSeverity(CompilerOptions.FinalParameterBound);
-
- case IProblem.MissingSerialVersion:
- return this.options.getSeverity(CompilerOptions.MissingSerialVersion);
-
- case IProblem.ForbiddenReference:
- return this.options.getSeverity(CompilerOptions.ForbiddenReference);
-
- case IProblem.DiscouragedReference:
- return this.options.getSeverity(CompilerOptions.DiscouragedReference);
-
- case IProblem.MethodVarargsArgumentNeedCast :
- case IProblem.ConstructorVarargsArgumentNeedCast :
- return this.options.getSeverity(CompilerOptions.VarargsArgumentNeedCast);
-
- case IProblem.LocalVariableCannotBeNull :
- case IProblem.LocalVariableCanOnlyBeNull :
- return this.options.getSeverity(CompilerOptions.NullReference);
-
- case IProblem.BoxingConversion :
- case IProblem.UnboxingConversion :
- return this.options.getSeverity(CompilerOptions.Autoboxing);
-
- case IProblem.MissingEnumConstantCase :
- return this.options.getSeverity(CompilerOptions.IncompleteEnumSwitch);
-
- case IProblem.VarargsConflict :
- return Warning;
-
- case IProblem.AnnotationTypeUsedAsSuperInterface :
- return this.options.getSeverity(CompilerOptions.AnnotationSuperInterface);
-
- /*
- * Javadoc syntax errors
- */
- case IProblem.JavadocUnexpectedTag:
- case IProblem.JavadocDuplicateReturnTag:
- case IProblem.JavadocInvalidThrowsClass:
- case IProblem.JavadocInvalidReference:
- case IProblem.JavadocInvalidParamTagName:
- case IProblem.JavadocInvalidParamTagTypeParameter:
- case IProblem.JavadocMalformedSeeReference:
- case IProblem.JavadocInvalidSeeHref:
- case IProblem.JavadocInvalidSeeArgs:
- case IProblem.JavadocInvalidTag:
- case IProblem.JavadocUnterminatedInlineTag:
- case IProblem.JavadocMissingHashCharacter:
- case IProblem.JavadocEmptyReturnTag:
- case IProblem.JavadocUnexpectedText:
- if (this.options.docCommentSupport) {
- return this.options.getSeverity(CompilerOptions.InvalidJavadoc);
- } else {
- return ProblemSeverities.Ignore;
- }
-
/*
* Javadoc tags resolved references errors
*/
@@ -759,7 +575,7 @@
case IProblem.JavadocInvalidThrowsClassName:
case IProblem.JavadocDuplicateThrowsClassName:
case IProblem.JavadocMissingThrowsClassName:
- case IProblem.JavadocMissingReference:
+ case IProblem.JavadocMissingSeeReference:
case IProblem.JavadocInvalidValueReference:
case IProblem.JavadocUndefinedField:
case IProblem.JavadocAmbiguousField:
@@ -777,6 +593,7 @@
case IProblem.JavadocInheritedMethodHidesEnclosingName:
case IProblem.JavadocInheritedFieldHidesEnclosingName:
case IProblem.JavadocInheritedNameHidesEnclosingTypeName:
+ case ProblemReporter.JavadocNonStaticTypeFromStaticInvocation: // internal problem ID in 3.1 maintenance branch
case IProblem.JavadocGenericMethodTypeArgumentMismatch:
case IProblem.JavadocNonGenericMethod:
case IProblem.JavadocIncorrectArityForParameterizedMethod:
@@ -787,11 +604,10 @@
case IProblem.JavadocIncorrectArityForParameterizedConstructor:
case IProblem.JavadocParameterizedConstructorArgumentTypeMismatch:
case IProblem.JavadocTypeArgumentsForRawGenericConstructor:
- if (this.options.docCommentSupport && this.options.reportInvalidJavadocTags) {
- return this.options.getSeverity(CompilerOptions.InvalidJavadoc);
+ if (!this.options.reportInvalidJavadocTags) {
+ return ProblemSeverities.Ignore;
}
- return ProblemSeverities.Ignore;
-
+ break;
/*
* Javadoc invalid tags due to deprecated references
*/
@@ -799,11 +615,10 @@
case IProblem.JavadocUsingDeprecatedConstructor:
case IProblem.JavadocUsingDeprecatedMethod:
case IProblem.JavadocUsingDeprecatedType:
- if (this.options.docCommentSupport && this.options.reportInvalidJavadocTags && this.options.reportInvalidJavadocTagsDeprecatedRef) {
- return this.options.getSeverity(CompilerOptions.InvalidJavadoc);
+ if (!(this.options.reportInvalidJavadocTags && this.options.reportInvalidJavadocTagsDeprecatedRef)) {
+ return ProblemSeverities.Ignore;
}
- return ProblemSeverities.Ignore;
-
+ break;
/*
* Javadoc invalid tags due to non-visible references
*/
@@ -811,37 +626,18 @@
case IProblem.JavadocNotVisibleConstructor:
case IProblem.JavadocNotVisibleMethod:
case IProblem.JavadocNotVisibleType:
- if (this.options.docCommentSupport && this.options.reportInvalidJavadocTags && this.options.reportInvalidJavadocTagsNotVisibleRef) {
- return this.options.getSeverity(CompilerOptions.InvalidJavadoc);
+ if (!(this.options.reportInvalidJavadocTags && this.options.reportInvalidJavadocTagsNotVisibleRef)) {
+ return ProblemSeverities.Ignore;
}
- return ProblemSeverities.Ignore;
-
- /*
- * Javadoc missing tags errors
- */
- case IProblem.JavadocMissingParamTag:
- case IProblem.JavadocMissingReturnTag:
- case IProblem.JavadocMissingThrowsTag:
- if (this.options.docCommentSupport) {
- return this.options.getSeverity(CompilerOptions.MissingJavadocTags);
- } else {
- return ProblemSeverities.Ignore;
- }
-
- /*
- * Missing Javadoc errors
- */
- case IProblem.JavadocMissing:
- if (this.options.docCommentSupport) {
- return this.options.getSeverity(CompilerOptions.MissingJavadocComments);
- } else {
- return ProblemSeverities.Ignore;
- }
-
- // by default problems are errors.
- default:
- return Error;
+ break;
}
+ long irritant = getIrritant(problemID);
+ if (irritant != 0) {
+ if ((problemID & IProblem.Javadoc) != 0 && !this.options.docCommentSupport)
+ return ProblemSeverities.Ignore;
+ return this.options.getSeverity(irritant);
+ }
+ return Error;
}
public void conditionalArgumentsIncompatibleTypes(ConditionalExpression expression, TypeBinding trueType, TypeBinding falseType) {
this.handle(
@@ -928,8 +724,8 @@
IProblem.UsingDeprecatedField,
new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
- location.sourceStart,
- location.sourceEnd);
+ fieldSourceStart(field, location),
+ fieldSourceEnd(field, location));
}
public void deprecatedMethod(MethodBinding method, ASTNode location) {
if (method.isConstructor()) {
@@ -1062,8 +858,8 @@
IProblem.DuplicateBlankFinalFieldInitialization,
arguments,
arguments,
- reference.sourceStart,
- reference.sourceEnd);
+ fieldSourceStart(field, reference),
+ fieldSourceEnd(field, reference));
}
public void duplicateInitializationOfFinalLocal(LocalVariableBinding local, ASTNode location) {
String[] arguments = new String[] { new String(local.readableName())};
@@ -1176,7 +972,7 @@
typeDecl.sourceStart,
typeDecl.sourceEnd);
}
-public void duplicateSuperinterface(SourceTypeBinding type, TypeDeclaration typeDecl, ReferenceBinding superType) {
+public void duplicateSuperinterface(SourceTypeBinding type, TypeReference reference, ReferenceBinding superType) {
this.handle(
IProblem.DuplicateSuperInterface,
new String[] {
@@ -1185,17 +981,18 @@
new String[] {
new String(superType.shortReadableName()),
new String(type.sourceName())},
- typeDecl.sourceStart,
- typeDecl.sourceEnd);
+ reference.sourceStart,
+ reference.sourceEnd);
}
public void duplicateTargetInTargetAnnotation(TypeBinding annotationType, NameReference reference) {
- String name = new String(reference.fieldBinding().name);
+ FieldBinding field = reference.fieldBinding();
+ String name = new String(field.name);
this.handle(
IProblem.DuplicateTargetInTargetAnnotation,
new String[] { name, new String(annotationType.readableName())},
new String[] { name, new String(annotationType.shortReadableName())},
- reference.sourceStart,
- reference.sourceEnd);
+ fieldSourceStart(field, reference),
+ fieldSourceEnd(field, reference));
}
public void duplicateTypeParameterInType(TypeParameter typeParameter) {
this.handle(
@@ -1243,13 +1040,21 @@
method.sourceStart(),
method.sourceEnd());
}
+public void enumStaticFieldUsedDuringInitialization(FieldBinding field, ASTNode location) {
+ this.handle(
+ ProblemReporter.EnumStaticFieldInInInitializerContext, // internal problem ID in 3.1 maintenance branch
+ new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
+ new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
+ fieldSourceStart(field, location),
+ fieldSourceEnd(field, location));
+}
public void enumSwitchCannotTargetField(Reference reference, FieldBinding field) {
this.handle(
IProblem.EnumSwitchCannotTargetField,
new String[]{ String.valueOf(field.declaringClass.readableName()), String.valueOf(field.name) },
new String[]{ String.valueOf(field.declaringClass.shortReadableName()), String.valueOf(field.name) },
- reference.sourceStart,
- reference.sourceEnd);
+ fieldSourceStart(field, reference),
+ fieldSourceEnd(field, reference));
}
public void errorNoMethodFor(MessageSend messageSend, TypeBinding recType, TypeBinding[] params) {
StringBuffer buffer = new StringBuffer();
@@ -1327,7 +1132,8 @@
fieldDecl.sourceEnd);
}
}
-private int fieldLocation(FieldBinding field, ASTNode node) {
+
+private int fieldSourceEnd(FieldBinding field, ASTNode node) {
if (node instanceof QualifiedNameReference) {
QualifiedNameReference ref = (QualifiedNameReference) node;
FieldBinding[] bindings = ref.otherBindings;
@@ -1338,6 +1144,14 @@
}
return node.sourceEnd;
}
+private int fieldSourceStart(FieldBinding field, ASTNode node) {
+ if (node instanceof FieldReference) {
+ FieldReference fieldReference = (FieldReference) node;
+ return (int) (fieldReference.nameSourcePosition >> 32);
+ }
+ return node.sourceStart;
+}
+
public void fieldsOrThisBeforeConstructorInvocation(ThisReference reference) {
this.handle(
IProblem.ThisSuperDuringConstructorInvocation,
@@ -1406,6 +1220,238 @@
typeDecl.superclass.sourceStart,
typeDecl.superclass.sourceEnd);
}
+public static long getIrritant(int problemID) {
+ switch(problemID){
+
+ case IProblem.MaskedCatch :
+ return CompilerOptions.MaskedCatchBlock;
+
+ case IProblem.UnusedImport :
+ return CompilerOptions.UnusedImport;
+
+ case IProblem.MethodButWithConstructorName :
+ return CompilerOptions.MethodWithConstructorName;
+
+ case IProblem.OverridingNonVisibleMethod :
+ return CompilerOptions.OverriddenPackageDefaultMethod;
+
+ case IProblem.IncompatibleReturnTypeForNonInheritedInterfaceMethod :
+ case IProblem.IncompatibleExceptionInThrowsClauseForNonInheritedInterfaceMethod :
+ return CompilerOptions.IncompatibleNonInheritedInterfaceMethod;
+
+ case IProblem.OverridingDeprecatedMethod :
+ case IProblem.UsingDeprecatedType :
+ case IProblem.UsingDeprecatedMethod :
+ case IProblem.UsingDeprecatedConstructor :
+ case IProblem.UsingDeprecatedField :
+ return CompilerOptions.UsingDeprecatedAPI;
+
+ case IProblem.LocalVariableIsNeverUsed :
+ return CompilerOptions.UnusedLocalVariable;
+
+ case IProblem.ArgumentIsNeverUsed :
+ return CompilerOptions.UnusedArgument;
+
+ case IProblem.NoImplicitStringConversionForCharArrayExpression :
+ return CompilerOptions.NoImplicitStringConversion;
+
+ case IProblem.NeedToEmulateFieldReadAccess :
+ case IProblem.NeedToEmulateFieldWriteAccess :
+ case IProblem.NeedToEmulateMethodAccess :
+ case IProblem.NeedToEmulateConstructorAccess :
+ return CompilerOptions.AccessEmulation;
+
+ case IProblem.NonExternalizedStringLiteral :
+ return CompilerOptions.NonExternalizedString;
+
+ case IProblem.UseAssertAsAnIdentifier :
+ return CompilerOptions.AssertUsedAsAnIdentifier;
+
+ case IProblem.UseEnumAsAnIdentifier :
+ return CompilerOptions.EnumUsedAsAnIdentifier;
+
+ case IProblem.NonStaticAccessToStaticMethod :
+ case IProblem.NonStaticAccessToStaticField :
+ return CompilerOptions.NonStaticAccessToStatic;
+
+ case IProblem.IndirectAccessToStaticMethod :
+ case IProblem.IndirectAccessToStaticField :
+ case IProblem.IndirectAccessToStaticType :
+ return CompilerOptions.IndirectStaticAccess;
+
+ case IProblem.AssignmentHasNoEffect:
+ return CompilerOptions.NoEffectAssignment;
+
+ case IProblem.UnusedPrivateConstructor:
+ case IProblem.UnusedPrivateMethod:
+ case IProblem.UnusedPrivateField:
+ case IProblem.UnusedPrivateType:
+ return CompilerOptions.UnusedPrivateMember;
+
+ case IProblem.LocalVariableHidingLocalVariable:
+ case IProblem.LocalVariableHidingField:
+ case IProblem.ArgumentHidingLocalVariable:
+ case IProblem.ArgumentHidingField:
+ return CompilerOptions.LocalVariableHiding;
+
+ case IProblem.FieldHidingLocalVariable:
+ case IProblem.FieldHidingField:
+ return CompilerOptions.FieldHiding;
+
+ case IProblem.TypeParameterHidingType:
+ return CompilerOptions.TypeParameterHiding;
+
+ case IProblem.PossibleAccidentalBooleanAssignment:
+ return CompilerOptions.AccidentalBooleanAssign;
+
+ case IProblem.SuperfluousSemicolon:
+ case IProblem.EmptyControlFlowStatement:
+ return CompilerOptions.EmptyStatement;
+
+ case IProblem.UndocumentedEmptyBlock:
+ return CompilerOptions.UndocumentedEmptyBlock;
+
+ case IProblem.UnnecessaryCast:
+ case IProblem.UnnecessaryInstanceof:
+ return CompilerOptions.UnnecessaryTypeCheck;
+
+ case IProblem.FinallyMustCompleteNormally:
+ return CompilerOptions.FinallyBlockNotCompleting;
+
+ case IProblem.UnusedMethodDeclaredThrownException:
+ case IProblem.UnusedConstructorDeclaredThrownException:
+ return CompilerOptions.UnusedDeclaredThrownException;
+
+ case IProblem.UnqualifiedFieldAccess:
+ return CompilerOptions.UnqualifiedFieldAccess;
+
+ case IProblem.UnnecessaryElse:
+ return CompilerOptions.UnnecessaryElse;
+
+ case IProblem.UnsafeRawConstructorInvocation:
+ case IProblem.UnsafeRawMethodInvocation:
+ case IProblem.UnsafeTypeConversion:
+ case IProblem.UnsafeRawFieldAssignment:
+ case IProblem.UnsafeGenericCast:
+ case IProblem.UnsafeReturnTypeOverride:
+ case IProblem.UnsafeRawGenericMethodInvocation:
+ case IProblem.UnsafeRawGenericConstructorInvocation:
+ return CompilerOptions.UncheckedTypeOperation;
+
+ case IProblem.MissingOverrideAnnotation:
+ return CompilerOptions.MissingOverrideAnnotation;
+
+ case IProblem.FieldMissingDeprecatedAnnotation:
+ case IProblem.MethodMissingDeprecatedAnnotation:
+ case IProblem.TypeMissingDeprecatedAnnotation:
+ return CompilerOptions.MissingDeprecatedAnnotation;
+
+ case IProblem.FinalBoundForTypeVariable:
+ return CompilerOptions.FinalParameterBound;
+
+ case IProblem.MissingSerialVersion:
+ return CompilerOptions.MissingSerialVersion;
+
+ case IProblem.ForbiddenReference:
+ return CompilerOptions.ForbiddenReference;
+
+ case IProblem.DiscouragedReference:
+ return CompilerOptions.DiscouragedReference;
+
+ case IProblem.MethodVarargsArgumentNeedCast :
+ case IProblem.ConstructorVarargsArgumentNeedCast :
+ return CompilerOptions.VarargsArgumentNeedCast;
+
+ case IProblem.LocalVariableCannotBeNull :
+ case IProblem.LocalVariableCanOnlyBeNull :
+ return CompilerOptions.NullReference;
+
+ case IProblem.BoxingConversion :
+ case IProblem.UnboxingConversion :
+ return CompilerOptions.Autoboxing;
+
+ case IProblem.MissingEnumConstantCase :
+ return CompilerOptions.IncompleteEnumSwitch;
+
+ case IProblem.AnnotationTypeUsedAsSuperInterface :
+ return CompilerOptions.AnnotationSuperInterface;
+
+ case IProblem.UnhandledWarningToken :
+ return CompilerOptions.UnhandledWarningToken;
+
+ case IProblem.JavadocUnexpectedTag:
+ case IProblem.JavadocDuplicateReturnTag:
+ case IProblem.JavadocInvalidThrowsClass:
+ case IProblem.JavadocInvalidSeeReference:
+ case IProblem.JavadocInvalidParamTagName:
+ case IProblem.JavadocInvalidParamTagTypeParameter:
+ case IProblem.JavadocMalformedSeeReference:
+ case IProblem.JavadocInvalidSeeHref:
+ case IProblem.JavadocInvalidSeeArgs:
+ case IProblem.JavadocInvalidTag:
+ case IProblem.JavadocUnterminatedInlineTag:
+ case IProblem.JavadocMissingHashCharacter:
+ case IProblem.JavadocEmptyReturnTag:
+ case IProblem.JavadocUnexpectedText:
+ case IProblem.JavadocInvalidParamName:
+ case IProblem.JavadocDuplicateParamName:
+ case IProblem.JavadocMissingParamName:
+ case IProblem.JavadocInvalidThrowsClassName:
+ case IProblem.JavadocDuplicateThrowsClassName:
+ case IProblem.JavadocMissingThrowsClassName:
+ case IProblem.JavadocMissingSeeReference:
+ case IProblem.JavadocInvalidValueReference:
+ case IProblem.JavadocUndefinedField:
+ case IProblem.JavadocAmbiguousField:
+ case IProblem.JavadocUndefinedConstructor:
+ case IProblem.JavadocAmbiguousConstructor:
+ case IProblem.JavadocUndefinedMethod:
+ case IProblem.JavadocAmbiguousMethod:
+ case IProblem.JavadocAmbiguousMethodReference:
+ case IProblem.JavadocParameterMismatch:
+ case IProblem.JavadocUndefinedType:
+ case IProblem.JavadocAmbiguousType:
+ case IProblem.JavadocInternalTypeNameProvided:
+ case IProblem.JavadocNoMessageSendOnArrayType:
+ case IProblem.JavadocNoMessageSendOnBaseType:
+ case IProblem.JavadocInheritedMethodHidesEnclosingName:
+ case IProblem.JavadocInheritedFieldHidesEnclosingName:
+ case IProblem.JavadocInheritedNameHidesEnclosingTypeName:
+ case ProblemReporter.JavadocNonStaticTypeFromStaticInvocation: // internal problem ID in 3.1 maintenance branch
+ case IProblem.JavadocGenericMethodTypeArgumentMismatch:
+ case IProblem.JavadocNonGenericMethod:
+ case IProblem.JavadocIncorrectArityForParameterizedMethod:
+ case IProblem.JavadocParameterizedMethodArgumentTypeMismatch:
+ case IProblem.JavadocTypeArgumentsForRawGenericMethod:
+ case IProblem.JavadocGenericConstructorTypeArgumentMismatch:
+ case IProblem.JavadocNonGenericConstructor:
+ case IProblem.JavadocIncorrectArityForParameterizedConstructor:
+ case IProblem.JavadocParameterizedConstructorArgumentTypeMismatch:
+ case IProblem.JavadocTypeArgumentsForRawGenericConstructor:
+ case IProblem.JavadocNotVisibleField:
+ case IProblem.JavadocNotVisibleConstructor:
+ case IProblem.JavadocNotVisibleMethod:
+ case IProblem.JavadocNotVisibleType:
+ return CompilerOptions.InvalidJavadoc;
+
+ case IProblem.JavadocUsingDeprecatedField:
+ case IProblem.JavadocUsingDeprecatedConstructor:
+ case IProblem.JavadocUsingDeprecatedMethod:
+ case IProblem.JavadocUsingDeprecatedType:
+ return CompilerOptions.InvalidJavadoc | CompilerOptions.UsingDeprecatedAPI;
+
+ case IProblem.JavadocMissingParamTag:
+ case IProblem.JavadocMissingReturnTag:
+ case IProblem.JavadocMissingThrowsTag:
+ return CompilerOptions.MissingJavadocTags;
+
+ case IProblem.JavadocMissing:
+ return CompilerOptions.MissingJavadocComments;
+ }
+ return 0;
+
+}
+
// use this private API when the compilation unit result can be found through the
// reference context. Otherwise, use the other API taking a problem and a compilation result
// as arguments
@@ -2074,8 +2120,8 @@
IProblem.IndirectAccessToStaticField,
new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
- location.sourceStart,
- fieldLocation(field, location));
+ fieldSourceStart(field, location),
+ fieldSourceEnd(field, location));
}
public void indirectAccessToStaticMethod(ASTNode location, MethodBinding method) {
this.handle(
@@ -2281,24 +2327,27 @@
problemConstructor = (ProblemMethodBinding) targetConstructor;
ParameterizedGenericMethodBinding substitutedConstructor = (ParameterizedGenericMethodBinding) problemConstructor.closestMatch;
shownConstructor = substitutedConstructor.original();
- TypeBinding typeArgument = targetConstructor.parameters[0];
- TypeVariableBinding typeParameter = (TypeVariableBinding) targetConstructor.parameters[1];
+ int augmentedLength = problemConstructor.parameters.length;
+ TypeBinding inferredTypeArgument = problemConstructor.parameters[augmentedLength-2];
+ TypeVariableBinding typeParameter = (TypeVariableBinding) problemConstructor.parameters[augmentedLength-1];
+ TypeBinding[] invocationArguments = new TypeBinding[augmentedLength-2]; // remove extra info from the end
+ System.arraycopy(problemConstructor.parameters, 0, invocationArguments, 0, augmentedLength-2);
this.handle(
IProblem.GenericConstructorTypeArgumentMismatch,
new String[] {
new String(shownConstructor.declaringClass.sourceName()),
typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, false),
new String(shownConstructor.declaringClass.readableName()),
- typesAsString(substitutedConstructor.isVarargs(), substitutedConstructor.parameters, false),
- new String(typeArgument.readableName()),
+ typesAsString(false, invocationArguments, false),
+ new String(inferredTypeArgument.readableName()),
new String(typeParameter.sourceName),
parameterBoundAsString(typeParameter, false) },
new String[] {
new String(shownConstructor.declaringClass.sourceName()),
typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, true),
new String(shownConstructor.declaringClass.shortReadableName()),
- typesAsString(substitutedConstructor.isVarargs(), substitutedConstructor.parameters, true),
- new String(typeArgument.shortReadableName()),
+ typesAsString(false, invocationArguments, true),
+ new String(inferredTypeArgument.shortReadableName()),
new String(typeParameter.sourceName),
parameterBoundAsString(typeParameter, true) },
sourceStart,
@@ -2453,6 +2502,7 @@
public void invalidField(FieldReference fieldRef, TypeBinding searchedType) {
int id = IProblem.UndefinedField;
FieldBinding field = fieldRef.binding;
+ final int sourceStart= (int) (fieldRef.nameSourcePosition >> 32);
switch (field.problemId()) {
case NotFound :
id = IProblem.UndefinedField;
@@ -2462,8 +2512,13 @@
*/
break;
case NotVisible :
- id = IProblem.NotVisibleField;
- break;
+ this.handle(
+ IProblem.NotVisibleField,
+ new String[] {new String(fieldRef.token), new String(field.declaringClass.readableName())},
+ new String[] {new String(fieldRef.token), new String(field.declaringClass.shortReadableName())},
+ sourceStart,
+ fieldRef.sourceEnd);
+ return;
case Ambiguous :
id = IProblem.AmbiguousField;
break;
@@ -2496,7 +2551,7 @@
id,
arguments,
arguments,
- fieldRef.sourceStart,
+ sourceStart,
fieldRef.sourceEnd);
}
public void invalidField(NameReference nameRef, FieldBinding field) {
@@ -2506,8 +2561,15 @@
id = IProblem.UndefinedField;
break;
case NotVisible :
- id = IProblem.NotVisibleField;
- break;
+ char[] name = field.readableName();
+ name = CharOperation.lastSegment(name, '.');
+ this.handle(
+ IProblem.NotVisibleField,
+ new String[] {new String(name), new String(field.declaringClass.readableName())},
+ new String[] {new String(name), new String(field.declaringClass.shortReadableName())},
+ nameRef.sourceStart,
+ nameRef.sourceEnd);
+ return;
case Ambiguous :
id = IProblem.AmbiguousField;
break;
@@ -2576,8 +2638,14 @@
*/
break;
case NotVisible :
- id = IProblem.NotVisibleField;
- break;
+ String fieldName = new String(nameRef.tokens[index]);
+ this.handle(
+ IProblem.NotVisibleField,
+ new String[] {fieldName, new String(field.declaringClass.readableName())},
+ new String[] {fieldName, new String(field.declaringClass.shortReadableName())},
+ nameRef.sourceStart,
+ (int) nameRef.sourcePositions[index]);
+ return;
case Ambiguous :
id = IProblem.AmbiguousField;
break;
@@ -2629,13 +2697,9 @@
if (problemMethod.closestMatch != null) {
shownMethod = problemMethod.closestMatch;
String closestParameterTypeNames = typesAsString(shownMethod.isVarargs(), shownMethod.parameters, false);
- String parameterTypeNames = typesAsString(method.isVarargs(), method.parameters, false);
+ String parameterTypeNames = typesAsString(false, problemMethod.parameters, false);
String closestParameterTypeShortNames = typesAsString(shownMethod.isVarargs(), shownMethod.parameters, true);
- String parameterTypeShortNames = typesAsString(method.isVarargs(), method.parameters, true);
- if (closestParameterTypeShortNames.equals(parameterTypeShortNames)){
- closestParameterTypeShortNames = closestParameterTypeNames;
- parameterTypeShortNames = parameterTypeNames;
- }
+ String parameterTypeShortNames = typesAsString(false, problemMethod.parameters, true);
this.handle(
IProblem.ParameterMismatch,
new String[] {
@@ -2686,24 +2750,27 @@
problemMethod = (ProblemMethodBinding) method;
ParameterizedGenericMethodBinding substitutedMethod = (ParameterizedGenericMethodBinding) problemMethod.closestMatch;
shownMethod = substitutedMethod.original();
- TypeBinding typeArgument = method.parameters[0];
- TypeVariableBinding typeParameter = (TypeVariableBinding) method.parameters[1];
+ int augmentedLength = problemMethod.parameters.length;
+ TypeBinding inferredTypeArgument = problemMethod.parameters[augmentedLength-2];
+ TypeVariableBinding typeParameter = (TypeVariableBinding) problemMethod.parameters[augmentedLength-1];
+ TypeBinding[] invocationArguments = new TypeBinding[augmentedLength-2]; // remove extra info from the end
+ System.arraycopy(problemMethod.parameters, 0, invocationArguments, 0, augmentedLength-2);
this.handle(
IProblem.GenericMethodTypeArgumentMismatch,
new String[] {
new String(shownMethod.selector),
typesAsString(shownMethod.isVarargs(), shownMethod.parameters, false),
new String(shownMethod.declaringClass.readableName()),
- typesAsString(substitutedMethod.isVarargs(), substitutedMethod.parameters, false),
- new String(typeArgument.readableName()),
+ typesAsString(false, invocationArguments, false),
+ new String(inferredTypeArgument.readableName()),
new String(typeParameter.sourceName),
parameterBoundAsString(typeParameter, false) },
new String[] {
new String(shownMethod.selector),
typesAsString(shownMethod.isVarargs(), shownMethod.parameters, true),
new String(shownMethod.declaringClass.shortReadableName()),
- typesAsString(substitutedMethod.isVarargs(), substitutedMethod.parameters, true),
- new String(typeArgument.shortReadableName()),
+ typesAsString(false, invocationArguments, true),
+ new String(inferredTypeArgument.shortReadableName()),
new String(typeParameter.sourceName),
parameterBoundAsString(typeParameter, true) },
(int) (messageSend.nameSourcePosition >>> 32),
@@ -2892,7 +2959,7 @@
id = IProblem.InheritedTypeHidesEnclosingName;
break;
case NonStaticReferenceInStaticContext :
- id = IProblem.TypeVariableReferenceFromStaticContext;
+ id = IProblem.NonStaticTypeFromStaticInvocation;
break;
case IllegalSuperTypeVariable :
id = IProblem.IllegalTypeVariableSuperReference;
@@ -3242,24 +3309,29 @@
problemConstructor = (ProblemMethodBinding) targetConstructor;
ParameterizedGenericMethodBinding substitutedConstructor = (ParameterizedGenericMethodBinding) problemConstructor.closestMatch;
shownConstructor = substitutedConstructor.original();
- TypeBinding typeArgument = targetConstructor.parameters[0];
- TypeVariableBinding typeParameter = (TypeVariableBinding) targetConstructor.parameters[1];
+
+ int augmentedLength = problemConstructor.parameters.length;
+ TypeBinding inferredTypeArgument = problemConstructor.parameters[augmentedLength-2];
+ TypeVariableBinding typeParameter = (TypeVariableBinding) problemConstructor.parameters[augmentedLength-1];
+ TypeBinding[] invocationArguments = new TypeBinding[augmentedLength-2]; // remove extra info from the end
+ System.arraycopy(problemConstructor.parameters, 0, invocationArguments, 0, augmentedLength-2);
+
this.handle(
IProblem.JavadocGenericConstructorTypeArgumentMismatch,
new String[] {
new String(shownConstructor.declaringClass.sourceName()),
typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, false),
new String(shownConstructor.declaringClass.readableName()),
- typesAsString(substitutedConstructor.isVarargs(), substitutedConstructor.parameters, false),
- new String(typeArgument.readableName()),
+ typesAsString(false, invocationArguments, false),
+ new String(inferredTypeArgument.readableName()),
new String(typeParameter.sourceName),
parameterBoundAsString(typeParameter, false) },
new String[] {
new String(shownConstructor.declaringClass.sourceName()),
typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, true),
new String(shownConstructor.declaringClass.shortReadableName()),
- typesAsString(substitutedConstructor.isVarargs(), substitutedConstructor.parameters, true),
- new String(typeArgument.shortReadableName()),
+ typesAsString(false, invocationArguments, true),
+ new String(inferredTypeArgument.shortReadableName()),
new String(typeParameter.sourceName),
parameterBoundAsString(typeParameter, true) },
sourceStart,
@@ -3372,9 +3444,6 @@
case Ambiguous :
id = IProblem.JavadocAmbiguousField;
break;
- case InheritedNameHidesEnclosingName :
- id = IProblem.JavadocInheritedFieldHidesEnclosingName;
- break;
case NoError : // 0
default :
needImplementation(); // want to fail to see why we were here...
@@ -3437,31 +3506,31 @@
case Ambiguous :
id = IProblem.JavadocAmbiguousMethod;
break;
- case InheritedNameHidesEnclosingName :
- id = IProblem.JavadocInheritedMethodHidesEnclosingName;
- break;
case ParameterBoundMismatch :
problemMethod = (ProblemMethodBinding) method;
ParameterizedGenericMethodBinding substitutedMethod = (ParameterizedGenericMethodBinding) problemMethod.closestMatch;
shownMethod = substitutedMethod.original();
- TypeBinding typeArgument = method.parameters[0];
- TypeVariableBinding typeParameter = (TypeVariableBinding) method.parameters[1];
+ int augmentedLength = problemMethod.parameters.length;
+ TypeBinding inferredTypeArgument = problemMethod.parameters[augmentedLength-2];
+ TypeVariableBinding typeParameter = (TypeVariableBinding) problemMethod.parameters[augmentedLength-1];
+ TypeBinding[] invocationArguments = new TypeBinding[augmentedLength-2]; // remove extra info from the end
+ System.arraycopy(problemMethod.parameters, 0, invocationArguments, 0, augmentedLength-2);
this.handle(
IProblem.JavadocGenericMethodTypeArgumentMismatch,
new String[] {
new String(shownMethod.selector),
typesAsString(shownMethod.isVarargs(), shownMethod.parameters, false),
new String(shownMethod.declaringClass.readableName()),
- typesAsString(substitutedMethod.isVarargs(), substitutedMethod.parameters, false),
- new String(typeArgument.readableName()),
+ typesAsString(false, invocationArguments, false),
+ new String(inferredTypeArgument.readableName()),
new String(typeParameter.sourceName),
parameterBoundAsString(typeParameter, false) },
new String[] {
new String(shownMethod.selector),
typesAsString(shownMethod.isVarargs(), shownMethod.parameters, true),
new String(shownMethod.declaringClass.shortReadableName()),
- typesAsString(substitutedMethod.isVarargs(), substitutedMethod.parameters, true),
- new String(typeArgument.shortReadableName()),
+ typesAsString(false, invocationArguments, true),
+ new String(inferredTypeArgument.shortReadableName()),
new String(typeParameter.sourceName),
parameterBoundAsString(typeParameter, true) },
(int) (messageSend.nameSourcePosition >>> 32),
@@ -3566,7 +3635,7 @@
this.handle(IProblem.JavadocInvalidParamTagTypeParameter, NoArgument, NoArgument, sourceStart, sourceEnd);
}
public void javadocInvalidReference(int sourceStart, int sourceEnd) {
- this.handle(IProblem.JavadocInvalidReference, NoArgument, NoArgument, sourceStart, sourceEnd);
+ this.handle(IProblem.JavadocInvalidSeeReference, NoArgument, NoArgument, sourceStart, sourceEnd);
}
public void javadocInvalidSeeReferenceArgs(int sourceStart, int sourceEnd) {
this.handle(IProblem.JavadocInvalidSeeArgs, NoArgument, NoArgument, sourceStart, sourceEnd);
@@ -3605,6 +3674,9 @@
case InheritedNameHidesEnclosingName :
id = IProblem.JavadocInheritedNameHidesEnclosingTypeName;
break;
+ case NonStaticReferenceInStaticContext :
+ id = ProblemReporter.JavadocNonStaticTypeFromStaticInvocation; // internal problem ID in 3.1 maintenance branch
+ break;
case NoError : // 0
default :
needImplementation(); // want to fail to see why we were here...
@@ -3656,7 +3728,7 @@
}
public void javadocMissingReference(int sourceStart, int sourceEnd, int modifiers){
if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers))
- this.handle(IProblem.JavadocMissingReference, NoArgument, NoArgument, sourceStart, sourceEnd);
+ this.handle(IProblem.JavadocMissingSeeReference, NoArgument, NoArgument, sourceStart, sourceEnd);
}
public void javadocMissingReturnTag(int sourceStart, int sourceEnd, int modifiers){
boolean overriding = (modifiers & (CompilerModifiers.AccImplementing|CompilerModifiers.AccOverriding)) != 0;
@@ -3954,8 +4026,8 @@
: IProblem.NeedToEmulateFieldWriteAccess,
new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
- location.sourceStart,
- location.sourceEnd);
+ fieldSourceStart(field, location),
+ fieldSourceEnd(field, location));
}
public void needToEmulateMethodAccess(
MethodBinding method,
@@ -4075,8 +4147,8 @@
IProblem.NonStaticAccessToStaticField,
new String[] {new String(field.declaringClass.readableName()), new String(field.name)},
new String[] {new String(field.declaringClass.shortReadableName()), new String(field.name)},
- location.sourceStart,
- fieldLocation(field, location));
+ fieldSourceStart(field, location),
+ fieldSourceEnd(field, location));
}
public void nonStaticAccessToStaticMethod(ASTNode location, MethodBinding method) {
this.handle(
@@ -4773,8 +4845,8 @@
IProblem.NonStaticFieldFromStaticInvocation,
arguments,
arguments,
- location.sourceStart,
- fieldLocation(field, location));
+ fieldSourceStart(field,location),
+ fieldSourceEnd(field, location));
}
public void staticInheritedMethodConflicts(SourceTypeBinding type, MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
this.handle(
@@ -4840,13 +4912,13 @@
superInterfaceRef.sourceStart,
superInterfaceRef.sourceEnd);
}
-public void superinterfacesCollide(ReferenceBinding type, TypeDeclaration typeDecl, ReferenceBinding superType, ReferenceBinding inheritedSuperType) {
+public void superinterfacesCollide(TypeBinding type, ASTNode decl, TypeBinding superType, TypeBinding inheritedSuperType) {
this.handle(
IProblem.SuperInterfacesCollide,
new String[] {new String(superType.readableName()), new String(inheritedSuperType.readableName()), new String(type.sourceName())},
new String[] {new String(superType.shortReadableName()), new String(inheritedSuperType.shortReadableName()), new String(type.sourceName())},
- typeDecl.sourceStart,
- typeDecl.sourceEnd);
+ decl.sourceStart,
+ decl.sourceEnd);
}
public void superTypeCannotUseWildcard(SourceTypeBinding type, TypeReference superclass, TypeBinding superTypeBinding) {
String name = new String(type.sourceName());
@@ -5076,14 +5148,14 @@
location.sourceStart,
location.sourceEnd);
}
-public void uninitializedBlankFinalField(FieldBinding binding, ASTNode location) {
- String[] arguments = new String[] {new String(binding.readableName())};
+public void uninitializedBlankFinalField(FieldBinding field, ASTNode location) {
+ String[] arguments = new String[] {new String(field.readableName())};
this.handle(
IProblem.UninitializedBlankFinalField,
arguments,
arguments,
- location.sourceStart,
- fieldLocation(binding, location));
+ fieldSourceStart(field, location),
+ fieldSourceEnd(field, location));
}
public void uninitializedLocalVariable(LocalVariableBinding binding, ASTNode location) {
String[] arguments = new String[] {new String(binding.readableName())};
@@ -5171,6 +5243,15 @@
statement.sourceStart,
statement.sourceEnd);
}
+public void unhandledWarningToken(Expression token) {
+ String[] arguments = new String[] { token.constant.stringValue() };
+ this.handle(
+ IProblem.UnhandledWarningToken,
+ arguments,
+ arguments,
+ token.sourceStart,
+ token.sourceEnd);
+}
public void unresolvableReference(NameReference nameRef, Binding binding) {
int severity = Error;
/* also need to check that the searchedType is the receiver type
@@ -5214,15 +5295,15 @@
castExpression.sourceStart,
castExpression.sourceEnd);
}
-public void unsafeRawFieldAssignment(FieldBinding rawField, TypeBinding expressionType, ASTNode location) {
+public void unsafeRawFieldAssignment(FieldBinding field, TypeBinding expressionType, ASTNode location) {
this.handle(
IProblem.UnsafeRawFieldAssignment,
new String[] {
- new String(expressionType.readableName()), new String(rawField.name), new String(rawField.declaringClass.readableName()), new String(rawField.declaringClass.erasure().readableName()) },
+ new String(expressionType.readableName()), new String(field.name), new String(field.declaringClass.readableName()), new String(field.declaringClass.erasure().readableName()) },
new String[] {
- new String(expressionType.shortReadableName()), new String(rawField.name), new String(rawField.declaringClass.shortReadableName()), new String(rawField.declaringClass.erasure().shortReadableName()) },
- location.sourceStart,
- location.sourceEnd);
+ new String(expressionType.shortReadableName()), new String(field.name), new String(field.declaringClass.shortReadableName()), new String(field.declaringClass.erasure().shortReadableName()) },
+ fieldSourceStart(field,location),
+ fieldSourceEnd(field, location));
}
public void unsafeRawGenericMethodInvocation(ASTNode location, MethodBinding rawMethod) {
if (rawMethod.isConstructor()) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index 70fc600..7565007 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -15,7 +15,7 @@
4 = The type {0} is ambiguous
5 = The type {0} is deprecated
6 = The nested type {0} cannot be referenced using its binary name
-7 = The private type {0} is never used locally
+7 = The type {0} is never used locally
15 = Incompatible operand types {0} and {1}
16 = Incompatible conditional operand types {0} and {1}
@@ -57,13 +57,13 @@
68 = Too many array dimensions. Maximum is 255
69 = The code of constructor {0}({1}) is exceeding the 65535 bytes limit
70 = {0} cannot be resolved or is not a field
-71 = The field {0} is not visible
+71 = The field {1}.{0} is not visible
72 = The field {0} is ambiguous
73 = The field {0}.{1} is deprecated
74 = Cannot make a static reference to the non-static field {0}
75 = Cannot reference a field before it is defined
76 = The static field {0}.{1} should be accessed in a static way
-77 = The private field {0}.{1} is never read locally
+77 = The field {0}.{1} is never read locally
78 = The static field {0}.{1} should be accessed directly
79 = Unqualified access to the field {0}.{1}
80 = The final field {0}.{1} cannot be assigned
@@ -96,14 +96,14 @@
115 = The method {1}({2}) in the type {0} is not applicable for the arguments ({3})
116 = Cannot invoke {1}({2}) on the array type {0}
117 = The static method {1}({2}) from the type {0} should be accessed in a static way
-118 = The private method {1}({2}) from the type {0} is never used locally
+118 = The method {1}({2}) from the type {0} is never used locally
119 = The static method {1}({2}) from the type {0} should be accessed directly
130 = The constructor {0}({1}) is undefined
131 = The constructor {0}({1}) is not visible
132 = The constructor {0}({1}) is ambiguous
133 = The constructor {0}({1}) is deprecated
-134 = The private constructor {0}({1}) is never used locally
+134 = The constructor {0}({1}) is never used locally
135 = Cannot refer to an instance field {0} while explicitly invoking a constructor
136 = Cannot refer to an instance method while explicitly invoking a constructor
137 = Recursive constructor invocation {0}({1})
@@ -359,6 +359,7 @@
460 = Empty block should be documented
### DOC
+468 = Cannot make a static reference to the non-static type variable {0}
469 = Invalid param tag type parameter name
470 = Unexpected tag
471 = Missing tag for parameter {0}
@@ -403,18 +404,18 @@
510 = The type {0} is defined in an inherited type and an enclosing scope
511 = {0} is an ambiguous method reference or is not a field
512 = Missing closing brace for inline tag
-513 = Missing #: "{0}"
-514 = Malformed reference (missing end space separator)
-515 = Missing return type description
-516 = Only static field reference is allowed for @value tag
-517 = Unexpected text
-518 = Invalid param tag name
-519 = Javadoc:
+513 = Malformed reference (missing end space separator)
+514 = Javadoc:
+515 = Missing #: "{0}"
+516 = Missing return type description
+517 = Only static field reference is allowed for @value tag
+518 = Unexpected text
+519 = Invalid param tag name
### GENERICS
520 = Duplicate type parameter {0}
521 = Cannot refer to the type parameter {0} as a supertype
-522 = Cannot make a static reference to the type parameter {0}
+522 = Cannot make a static reference to the non-static type {0}
523 = The type java.lang.Object cannot be declared as a generic
524 = The type {0} is not generic; it cannot be parameterized with arguments <{1}>
525 = Incorrect number of arguments for type {0}; it cannot be parameterized with arguments <{1}>
@@ -435,8 +436,8 @@
540 = Bound mismatch: The constructor {0}({1}) of type {2} is not applicable for the arguments ({3}). The wildcard parameter {5} has no lower bound, and may actually be more restrictive than argument {4}
541 = Bound mismatch: The method {0}({1}) of type {2} is not applicable for the arguments ({3}). The wildcard parameter {5} has no lower bound, and may actually be more restrictive than argument {4}
542 = Bound mismatch: Cannot assign expression of type {0} to wildcard type {1}. The wildcard type has no lower bound, and may actually be more restrictive than expression type
-543 = Bound mismatch: The generic method {0}({1}) of type {2} is not applicable for the arguments ({3}) since the type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
-544 = Bound mismatch: The generic constructor {0}({1}) of type {2} is not applicable for the arguments ({3}) since the type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
+543 = Bound mismatch: The generic method {0}({1}) of type {2} is not applicable for the arguments ({3}). The inferred type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
+544 = Bound mismatch: The generic constructor {0}({1}) of type {2} is not applicable for the arguments ({3}). The inferred type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
545 = Type safety: The cast from {0} to {1} is actually checking against the erased type {2}
546 = Cannot perform instanceof check against parameterized type {0}. Use instead its raw form {1} since generic type information will be erased at runtime
547 = Cannot perform instanceof check against type parameter {0}. Use instead its erasure {1} since generic type information will be erased at runtime
@@ -456,7 +457,7 @@
561 = The member type {0}<{1}> must be qualified with a parameterized type, since it is not static
562 = The member type {0} must be parameterized, since it is qualified with a parameterized type
563 = The member type {0} cannot be qualified with a parameterized type, since it is static. Remove arguments from qualifying type {1}
-564 = Bound conflict: {0} is inherited with conflicting arguments
+###[obsolete] 564 = Bound conflict: {0} is inherited with conflicting arguments
565 = Duplicate methods named {0} with the parameters ({2}) and ({3}) are defined by the type {1}
566 = Cannot allocate the member type {0} using a parameterized compound name; use its simple name and an enclosing instance of type {1}
567 = Duplicate bound {0}
@@ -511,6 +512,7 @@
628 = The deprecated field {0}.{1} should be annotated with @Deprecated
629 = The deprecated method {0}({1}) of type {2} should be annotated with @Deprecated
630 = The deprecated type {0} should be annotated with @Deprecated
+631 = Unhandled warning token {0}
### CORRUPTED BINARIES
700 = The class file {0} contains a signature ''{1}'' ill-formed at position {2}
@@ -532,6 +534,7 @@
759 = The field {0}.{1} cannot be referenced from an enum case label; only enum constants can be used in enum switch
760 = Illegal modifier for the enum constructor; only private is permitted.
761 = The enum constant {0}.{1} has no corresponding case label
+762 = Cannot refer to the static enum field {0}.{1} within an initializer
### VARARGS
800 = Extended dimensions are illegal for a variable argument
@@ -540,12 +543,12 @@
803 = Varargs methods should only override other varargs methods unlike {2}.{0}({1}) and {4}.{0}({3})
### GENERIC JAVADOC
-850 = Bound mismatch: The generic method {0}({1}) of type {2} is not applicable for the arguments ({3}) since the type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
+850 = Bound mismatch: The generic method {0}({1}) of type {2} is not applicable for the arguments ({3}). The inferred type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
851 = The method {0}({1}) of type {2} is not generic; it cannot be parameterized with arguments <{3}>
852 = Incorrect number of type arguments for generic method <{3}>{0}({1}) of type {2}; it cannot be parameterized with arguments <{4}>
853 = The parameterized method <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4})
854 = The method {0}({1}) of raw type {2} is no longer generic; it cannot be parameterized with arguments <{3}>
-855 = Bound mismatch: The generic constructor {0}({1}) of type {2} is not applicable for the arguments ({3}) since the type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
+855 = Bound mismatch: The generic constructor {0}({1}) of type {2} is not applicable for the arguments ({3}). The inferred type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
856 = The constructor {0}({1}) of type {2} is not generic; it cannot be parameterized with arguments <{3}>
857 = Incorrect number of type arguments for generic constructor <{3}>{0}({1}) of type {2}; it cannot be parameterized with arguments <{4}>
858 = The parameterized constructor <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4})
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Messages.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Messages.java
index 67c23f7..9adcdf5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Messages.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Messages.java
@@ -71,7 +71,7 @@
private static String[] nlSuffixes;
private static final String EXTENSION = ".properties"; //$NON-NLS-1$
- private static final String BUNDLE_NAME = "org.eclipse.jdt.internal.compiler.util.messages";//$NON-NLS-1$
+ private static final String BUNDLE_NAME = "org.eclipse.jdt.internal.compiler.messages";//$NON-NLS-1$
private Messages() {
// Do not instantiate
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
index 63cb886..a43f75b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
@@ -29,7 +29,6 @@
private static final int DEFAULT_READING_SIZE = 8192;
public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
- public static char[] LINE_SEPARATOR_CHARS = LINE_SEPARATOR.toCharArray();
/**
* Returns the given bytes as a char array using a given encoding (null means platform default).
diff --git a/org.eclipse.jdt.core/component.xml b/org.eclipse.jdt.core/component.xml
new file mode 100644
index 0000000..c0ce337
--- /dev/null
+++ b/org.eclipse.jdt.core/component.xml
@@ -0,0 +1,308 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component xmlns="http://eclipse.org/component"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://eclipse.org/component ../component.xsd "
+ name="org.eclipse.jdt.core">
+ <plugin id="org.eclipse.jdt.core" />
+
+ <package name="org.eclipse.jdt.core">
+ <type name="BindingKey" subclass="false" />
+ <type name="BufferChangedEvent" subclass="false" instantiate="false"/>
+ <type name="ClasspathContainerInitializer" instantiate="false"/>
+ <type name="ClasspathVariableInitializer" instantiate="false"/>
+ <type name="CompletionContext" subclass="false" instantiate="false"/>
+ <type name="CompletionProposal" subclass="false" instantiate="false"/>
+ <type name="CompletionRequestor" instantiate="false"/>
+ <type name="CompletionRequestorAdapter"/>
+ <type name="CorrectionEngine" subclass="false"/>
+ <type name="ElementChangedEvent" subclass="false" instantiate="false"/>
+ <type name="Flags" subclass="false" instantiate="false"/>
+ <type name="IAccessRule"/>
+ <type name="IBuffer"/>
+ <type name="IBufferChangedListener"/>
+ <type name="IBufferFactory"/>
+ <type name="IClassFile" implement="false"/>
+ <type name="IClasspathAttribute" implement="false"/>
+ <type name="IClasspathContainer" implement="false"/>
+ <type name="IClasspathEntry" implement="false"/>
+ <type name="ICodeAssist" implement="false"/>
+ <type name="ICodeCompletionRequestor"/>
+ <type name="ICodeFormatter" implement="false"/>
+ <type name="ICompilationUnit" implement="false"/>
+ <type name="ICompletionRequestor"/>
+ <type name="ICorrectionRequestor" implement="false"/>
+ <type name="IElementChangedListener"/>
+ <type name="IField" implement="false"/>
+ <type name="IImportContainer" implement="false"/>
+ <type name="IImportDeclaration" implement="false"/>
+ <type name="IInitializer" implement="false"/>
+ <type name="IJavaElement" implement="false"/>
+ <type name="IJavaElementDelta" implement="false"/>
+ <type name="IJavaModel" implement="false"/>
+ <type name="IJavaModelMarker" implement="false"/>
+ <type name="IJavaModelStatus" implement="false"/>
+ <type name="IJavaModelStatusConstants" implement="false"/>
+ <type name="IJavaProject" implement="false"/>
+ <type name="ILocalVariable" implement="false"/>
+ <type name="IMember" implement="false"/>
+ <type name="IMethod" implement="false"/>
+ <type name="IOpenable" implement="false"/>
+ <type name="IPackageDeclaration" implement="false"/>
+ <type name="IPackageFragment" implement="false"/>
+ <type name="IPackageFragmentRoot" implement="false"/>
+ <type name="IParent" implement="false"/>
+ <type name="IProblemRequestor"/>
+ <type name="IRegion" implement="false"/>
+ <type name="ISourceManipulation" implement="false"/>
+ <type name="ISourceRange" implement="false"/>
+ <type name="ISourceReference" implement="false"/>
+ <type name="IType" implement="false"/>
+ <type name="ITypeHierarchy" implement="false"/>
+ <type name="ITypeHierarchyChangedListener"/>
+ <type name="ITypeParameter" implement="false"/>
+ <type name="IWorkingCopy" implement="false"/>
+ <type name="JavaConventions" subclass="false" instantiate="false"/>
+ <type name="JavaCore" subclass="false" instantiate="false"/>
+ <type name="JavaModelException" subclass="false" instantiate="false"/>
+ <type name="NamingConventions" subclass="false" instantiate="false"/>
+ <type name="Signature" subclass="false" instantiate="false"/>
+ <type name="ToolFactory" subclass="false" instantiate="false"/>
+ <type name="WorkingCopyOwner" instantiate="false"/>
+ </package>
+ <package name="org.eclipse.jdt.core.compiler">
+ <type name="IScanner" implement="false"/>
+ <type name="ITerminalSymbols" implement="false"/>
+ <type name="CharOperation" subclass="false" instantiate="false"/>
+ <type name="InvalidInputException" subclass="false" instantiate="false"/>
+ <type name="IProblem" implement="false"/>
+ </package>
+ <package name="org.eclipse.jdt.core.dom">
+ <type name="AbstractTypeDeclaration" instantiate="false"/>
+ <type name="Annotation" instantiate="false"/>
+ <type name="AnnotationTypeDeclaration" instantiate="false"/>
+ <type name="AnnotationTypeMemberDeclaration" instantiate="false"/>
+ <type name="AnonymousClassDeclaration" instantiate="false"/>
+ <type name="ArrayAccess" instantiate="false"/>
+ <type name="ArrayCreation" instantiate="false"/>
+ <type name="ArrayInitializer" instantiate="false"/>
+ <type name="ArrayType" instantiate="false"/>
+ <type name="AssertStatement" instantiate="false"/>
+ <type name="Assignment" instantiate="false"/>
+ <type name="AST" subclass="false" instantiate="false"/>
+ <type name="ASTConverter" reference="false"/>
+ <type name="ASTMatcher"/>
+ <type name="ASTNode" instantiate="false"/>
+ <type name="ASTParser" instantiate="false"/>
+ <type name="ASTRequestor" instantiate="false"/>
+ <type name="ASTSyntaxErrorPropagator" reference="false"/>
+ <type name="ASTVisitor"/>
+ <type name="BindingComparator" reference="false"/>
+ <type name="BindingResolver" reference="false"/>
+ <type name="Block" instantiate="false"/>
+ <type name="BlockComment" subclass="false" instantiate="false"/>
+ <type name="BodyDeclaration" instantiate="false"/>
+ <type name="BooleanLiteral" instantiate="false"/>
+ <type name="BreakStatement" instantiate="false"/>
+ <type name="CastExpression" instantiate="false"/>
+ <type name="CatchClause" instantiate="false"/>
+ <type name="CharacterLiteral" instantiate="false"/>
+ <type name="ChildListPropertyDescriptor" subclass="false" instantiate="false"/>
+ <type name="ChildPropertyDescriptor" subclass="false" instantiate="false"/>
+ <type name="ClassInstanceCreation" instantiate="false"/>
+ <type name="Comment" instantiate="false"/>
+ <type name="CompilationUnit" instantiate="false"/>
+ <type name="CompilationUnitResolver" reference="false"/>
+ <type name="ConditionalExpression" instantiate="false"/>
+ <type name="ConstructorInvocation" instantiate="false"/>
+ <type name="ContinueStatement" instantiate="false"/>
+ <type name="DefaultASTVisitor" reference="false"/>
+ <type name="DefaultBindingResolver" reference="false"/>
+ <type name="DefaultCommentMapper" reference="false"/>
+ <type name="DocCommentParser" reference="false"/>
+ <type name="DoStatement" instantiate="false"/>
+ <type name="EmptyStatement" instantiate="false"/>
+ <type name="EnhancedForStatement" instantiate="false"/>
+ <type name="EnumConstantDeclaration" instantiate="false"/>
+ <type name="EnumDeclaration" instantiate="false"/>
+ <type name="Expression" instantiate="false"/>
+ <type name="ExpressionStatement" instantiate="false"/>
+ <type name="FieldAccess" instantiate="false"/>
+ <type name="FieldDeclaration" instantiate="false"/>
+ <type name="ForStatement" instantiate="false"/>
+ <type name="IBinding" instantiate="false" implement="false"/>
+ <type name="IDocElement" reference="false"/>
+ <type name="IExtendedModifier" instantiate="false"/>
+ <type name="IfStatement" instantiate="false"/>
+ <type name="IMethodBinding" instantiate="false" implement="false"/>
+ <type name="ImportDeclaration" instantiate="false"/>
+ <type name="InfixExpression" instantiate="false"/>
+ <type name="Initializer" instantiate="false"/>
+ <type name="InstanceofExpression" instantiate="false"/>
+ <type name="InternalASTRewrite" reference="false"/>
+ <type name="IPackageBinding" implement="false"/>
+ <type name="ITypeBinding" implement="false"/>
+ <type name="IVariableBinding" implement="false"/>
+ <type name="Javadoc" instantiate="false"/>
+ <type name="LabeledStatement" instantiate="false"/>
+ <type name="LineComment" instantiate="false" subclass="false"/>
+ <type name="MarkerAnnotation" instantiate="false"/>
+ <type name="MemberRef" instantiate="false"/>
+ <type name="MemberValuePair" instantiate="false"/>
+ <type name="Message" instantiate="false"/>
+ <type name="MethodBinding" reference="false"/>
+ <type name="MethodDeclaration" instantiate="false"/>
+ <type name="MethodInvocation" instantiate="false"/>
+ <type name="MethodRef" instantiate="false"/>
+ <type name="MethodRefParameter" instantiate="false"/>
+ <type name="Modifier" instantiate="false" subclass="false"/>
+ <type name="NaiveASTFlattener" reference="false"/>
+ <type name="Name" instantiate="false"/>
+ <type name="NodeEventHandler" reference="false"/>
+ <type name="NodeSearcher" reference="false"/>
+ <type name="NormalAnnotation" instantiate="false"/>
+ <type name="NullLiteral" instantiate="false"/>
+ <type name="NumberLiteral" instantiate="false"/>
+ <type name="PackageBinding" reference="false"/>
+ <type name="PackageDeclaration" instantiate="false"/>
+ <type name="ParameterizedType" instantiate="false"/>
+ <type name="ParenthesizedExpression" instantiate="false"/>
+ <type name="PostfixExpression" instantiate="false"/>
+ <type name="PrefixExpression" instantiate="false"/>
+ <type name="PrimitiveType" instantiate="false"/>
+ <type name="QualifiedName" instantiate="false"/>
+ <type name="QualifiedType" instantiate="false"/>
+ <type name="ReturnStatement" instantiate="false"/>
+ <type name="SimpleName" instantiate="false"/>
+ <type name="SimplePropertyDescriptor" subclass="false" instantiate="false"/>
+ <type name="SimpleType" instantiate="false"/>
+ <type name="SingleMemberAnnotation" instantiate="false"/>
+ <type name="SingleVariableDeclaration" instantiate="false"/>
+ <type name="Statement" instantiate="false"/>
+ <type name="StringLiteral" instantiate="false"/>
+ <type name="StructuralPropertyDescriptor" subclass="false" instantiate="false"/>
+ <type name="SuperConstructorInvocation" instantiate="false"/>
+ <type name="SuperFieldAccess" instantiate="false"/>
+ <type name="SuperMethodInvocation" instantiate="false"/>
+ <type name="SwitchCase" instantiate="false"/>
+ <type name="SwitchStatement" instantiate="false"/>
+ <type name="SynchronizedStatement" instantiate="false"/>
+ <type name="TagElement" instantiate="false" subclass="false"/>
+ <type name="TextElement" instantiate="false" subclass="false"/>
+ <type name="ThisExpression" instantiate="false"/>
+ <type name="ThrowStatement" instantiate="false"/>
+ <type name="TryStatement" instantiate="false"/>
+ <type name="Type" instantiate="false"/>
+ <type name="TypeBinding" reference="false"/>
+ <type name="TypeDeclaration" instantiate="false"/>
+ <type name="TypeDeclarationStatement" instantiate="false"/>
+ <type name="TypeLiteral" instantiate="false"/>
+ <type name="TypeParameter" instantiate="false"/>
+ <type name="VariableBinding" reference="false"/>
+ <type name="VariableDeclaration" instantiate="false"/>
+ <type name="VariableDeclarationExpression" instantiate="false"/>
+ <type name="VariableDeclarationFragment" instantiate="false"/>
+ <type name="VariableDeclarationStatement" instantiate="false"/>
+ <type name="WhileStatement" instantiate="false"/>
+ <type name="WildcardType" instantiate="false"/>
+ </package>
+ <package name="org.eclipse.jdt.core.dom.rewrite">
+ <type name="ASTRewrite" subclass="false" instantiate="false"/>
+ <type name="ITrackedNodePosition" implement="false"/>
+ <type name="ListRewrite" subclass="false"/>
+ <type name="TargetSourceRangeComputer"/>
+ </package>
+ <package name="org.eclipse.jdt.core.eval">
+ <type name="ICodeSnippetRequestor"/>
+ <type name="IEvaluationContext" implement="false"/>
+ <type name="IGlobalVariable" implement="false"/>
+ </package>
+ <package name="org.eclipse.jdt.core.formatter">
+ <type name="CodeFormatter"/>
+ <type name="DefaultCodeFormatterConstants" subclass="false" instantiate="false"/>
+ </package>
+ <package name="org.eclipse.jdt.core.jdom">
+ <type name="DOMException"/>
+ <type name="DOMFactory" subclass="false"/>
+ <type name="IDOMCompilationUnit" implement="false"/>
+ <type name="IDOMFactory" implement="false"/>
+ <type name="IDOMField" implement="false"/>
+ <type name="IDOMImport" implement="false"/>
+ <type name="IDOMInitializer" implement="false"/>
+ <type name="IDOMMember" implement="false"/>
+ <type name="IDOMMethod" implement="false"/>
+ <type name="IDOMNode" implement="false"/>
+ <type name="IDOMPackage" implement="false"/>
+ <type name="IDOMType" implement="false"/>
+ </package>
+ <package name="org.eclipse.jdt.core.search">
+ <type name="FieldDeclarationMatch"/>
+ <type name="FieldReferenceMatch"/>
+ <type name="IJavaSearchConstants" implement="false"/>
+ <type name="IJavaSearchResultCollector"/>
+ <type name="IJavaSearchScope"/>
+ <type name="ISearchPattern"/>
+ <type name="ITypeNameRequestor"/>
+ <type name="LocalVariableDeclarationMatch"/>
+ <type name="LocalVariableReferenceMatch"/>
+ <type name="MethodDeclarationMatch"/>
+ <type name="MethodReferenceMatch"/>
+ <type name="PackageDeclarationMatch"/>
+ <type name="PackageReferenceMatch"/>
+ <type name="SearchDocument" instantiate="false"/>
+ <type name="SearchEngine" subclass="false"/>
+ <type name="SearchMatch"/>
+ <type name="SearchParticipant" instantiate="false"/>
+ <type name="SearchPattern" instantiate="false"/>
+ <type name="SearchRequestor" instantiate="false"/>
+ <type name="TypeDeclarationMatch"/>
+ <type name="TypeNameRequestor" instantiate="false"/>
+ <type name="TypeParameterDeclarationMatch"/>
+ <type name="TypeParameterReferenceMatch"/>
+ <type name="TypeReferenceMatch"/>
+ </package>
+ <package name="org.eclipse.jdt.core.util">
+ <type name="ByteCodeVisitorAdapter"/>
+ <type name="ClassFileBytesDisassembler"/>
+ <type name="ClassFormatException"/>
+ <type name="CompilationUnitSorter" subclass="false" instantiate="false"/>
+ <type name="IAnnotation"/>
+ <type name="IAnnotationComponent"/>
+ <type name="IAnnotationComponentValue"/>
+ <type name="IAnnotationDefaultAttribute"/>
+ <type name="IAttributeNamesConstants" implement="false"/>
+ <type name="IBytecodeVisitor" implement="false"/>
+ <type name="IClassFileAttribute"/>
+ <type name="IClassFileDisassembler"/>
+ <type name="IClassFileReader"/>
+ <type name="ICodeAttribute"/>
+ <type name="IConstantPool"/>
+ <type name="IConstantPoolConstant" implement="false"/>
+ <type name="IConstantPoolEntry"/>
+ <type name="IConstantValueAttribute"/>
+ <type name="IEnclosingMethodAttribute"/>
+ <type name="IExceptionAttribute"/>
+ <type name="IExceptionTableEntry"/>
+ <type name="IFieldInfo"/>
+ <type name="IInnerClassesAttribute"/>
+ <type name="IInnerClassesAttributeEntry"/>
+ <type name="ILineNumberAttribute"/>
+ <type name="ILocalVariableAttribute"/>
+ <type name="ILocalVariableTableEntry"/>
+ <type name="ILocalVariableTypeTableAttribute"/>
+ <type name="ILocalVariableTypeTableEntry"/>
+ <type name="IMethodInfo"/>
+ <type name="IModifierConstants" implement="false"/>
+ <type name="IOpcodeMnemonics" implement="false"/>
+ <type name="IParameterAnnotation"/>
+ <type name="IRuntimeInvisibleAnnotationsAttribute"/>
+ <type name="IRuntimeInvisibleParameterAnnotationsAttribute"/>
+ <type name="IRuntimeVisibleAnnotationsAttribute"/>
+ <type name="IRuntimeVisibleParameterAnnotationsAttribute"/>
+ <type name="ISignatureAttribute"/>
+ <type name="ISourceAttribute"/>
+ <type name="IVerificationTypeInfo"/>
+ <type name="OpcodeStringValues" subclass="false" instantiate="false"/>
+ </package>
+
+<component-depends unrestricted="true"/>
+</component>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index 254116f..3d460c4 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -58,6 +58,7 @@
protected AST ast;
protected Comment[] commentsTable;
char[] compilationUnitSource;
+ int compilationUnitSourceLength;
protected DocCommentParser docParser;
// comments
protected boolean insideComments;
@@ -360,8 +361,6 @@
setModifiers(initializer, oldInitializer);
initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
// The javadoc comment is now got from list store in compilation unit declaration
-// setJavaDocComment(initializer);
-// initializer.setJavadoc(convert(oldInitializer.javadoc));
convert(oldInitializer.javadoc, initializer);
bodyDeclarations.add(initializer);
return;
@@ -550,11 +549,14 @@
}
// The javadoc comment is now got from list store in compilation unit declaration
- convert(methodDeclaration.javadoc, methodDecl);
if (this.resolveBindings) {
recordNodes(methodDecl, methodDeclaration);
recordNodes(methodName, methodDeclaration);
- methodDecl.resolveBinding();
+ if (methodDecl.resolveBinding() != null) {
+ convert(methodDeclaration.javadoc, methodDecl);
+ }
+ } else {
+ convert(methodDeclaration.javadoc, methodDecl);
}
return methodDecl;
}
@@ -761,7 +763,7 @@
int previousSearchStart = end;
ArrayType componentType = (ArrayType) type.getParent();
for (int i = 0; i < dimensionsLength; i++) {
- previousSearchStart = retrieveRightBracketPosition(previousSearchStart + 1, this.compilationUnitSource.length);
+ previousSearchStart = retrieveRightBracketPosition(previousSearchStart + 1, this.compilationUnitSourceLength);
componentType.setSourceRange(start, previousSearchStart - start + 1);
componentType = (ArrayType) componentType.getParent();
}
@@ -817,7 +819,7 @@
assertStatement.setMessage(convert(exceptionArgument));
}
int start = statement.sourceStart;
- int sourceEnd = retrieveEndingSemiColonPosition(end, this.compilationUnitSource.length);
+ int sourceEnd = retrieveEndingSemiColonPosition(end, this.compilationUnitSourceLength);
assertStatement.setSourceRange(start, sourceEnd - start + 1);
return assertStatement;
}
@@ -1122,8 +1124,16 @@
public CompilationUnit convert(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) {
this.compilationUnitSource = source;
- this.scanner.setSource(unit.compilationResult);
+ this.compilationUnitSourceLength = source.length;
+ this.scanner.setSource(source, unit.compilationResult);
CompilationUnit compilationUnit = new CompilationUnit(this.ast);
+
+ // Parse comments
+ int[][] comments = unit.comments;
+ if (comments != null) {
+ buildCommentsTable(compilationUnit, comments);
+ }
+
// handle the package declaration immediately
// There is no node corresponding to the package declaration
if (this.resolveBindings) {
@@ -1141,12 +1151,6 @@
}
}
- // Parse comments
- int[][] comments = unit.comments;
- if (comments != null) {
- buildCommentsTable(compilationUnit, comments);
- }
-
org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = unit.types;
if (types != null) {
int typesLength = types.length;
@@ -1168,11 +1172,12 @@
int problemLength = unit.compilationResult.problemCount;
if (problemLength != 0) {
IProblem[] resizedProblems = null;
- final IProblem[] problems = unit.compilationResult.problems;
- if (problems.length == problemLength) {
+ final IProblem[] problems = unit.compilationResult.getProblems();
+ final int realProblemLength=problems.length;
+ if (realProblemLength == problemLength) {
resizedProblems = problems;
} else {
- System.arraycopy(problems, 0, (resizedProblems = new IProblem[problemLength]), 0, problemLength);
+ System.arraycopy(problems, 0, (resizedProblems = new IProblem[realProblemLength]), 0, realProblemLength);
}
ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(resizedProblems);
compilationUnit.accept(syntaxErrorPropagator);
@@ -1227,6 +1232,9 @@
break;
}
assignment.setRightHandSide(convert(expression.expression));
+ if (this.resolveBindings) {
+ recordNodes(assignment, expression);
+ }
return assignment;
}
@@ -1323,11 +1331,13 @@
} else {
enumConstantDeclaration.setSourceRange(declarationSourceStart, declarationSourceEnd - declarationSourceStart + 1);
}
+ setModifiers(enumConstantDeclaration, enumConstant);
if (this.resolveBindings) {
recordNodes(enumConstantDeclaration, enumConstant);
recordNodes(typeName, enumConstant);
enumConstantDeclaration.resolveVariable();
}
+ convert(enumConstant.javadoc, enumConstantDeclaration);
return enumConstantDeclaration;
}
@@ -1744,6 +1754,29 @@
}
}
}
+
+ public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, PackageDeclaration packageDeclaration) {
+ if (ast.apiLevel == AST.JLS3 && packageDeclaration.getJavadoc() == null) {
+ if (javadoc != null) {
+ if (this.commentMapper == null || !this.commentMapper.hasSameTable(this.commentsTable)) {
+ this.commentMapper = new DefaultCommentMapper(this.commentsTable);
+ }
+ Comment comment = this.commentMapper.getComment(javadoc.sourceStart);
+ if (comment != null && comment.isDocComment() && comment.getParent() == null) {
+ Javadoc docComment = (Javadoc) comment;
+ if (this.resolveBindings) {
+ recordNodes(docComment, javadoc);
+ // resolve member and method references binding
+ Iterator tags = docComment.tags().listIterator();
+ while (tags.hasNext()) {
+ recordNodes(javadoc, (TagElement) tags.next());
+ }
+ }
+ packageDeclaration.setJavadoc(docComment);
+ }
+ }
+ }
+ }
public LabeledStatement convert(org.eclipse.jdt.internal.compiler.ast.LabeledStatement statement) {
LabeledStatement labeledStatement = new LabeledStatement(this.ast);
@@ -2621,6 +2654,8 @@
if (this.resolveBindings) {
recordNodes(packageDeclaration, importReference);
}
+ // Set javadoc
+ convert(compilationUnitDeclaration.javadoc, packageDeclaration);
return packageDeclaration;
}
@@ -2660,15 +2695,18 @@
VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(fieldDecl);
final FieldDeclaration fieldDeclaration = new FieldDeclaration(this.ast);
fieldDeclaration.fragments().add(variableDeclarationFragment);
+ IVariableBinding binding = null;
if (this.resolveBindings) {
recordNodes(variableDeclarationFragment, fieldDecl);
- variableDeclarationFragment.resolveBinding();
+ binding = variableDeclarationFragment.resolveBinding();
}
fieldDeclaration.setSourceRange(fieldDecl.declarationSourceStart, fieldDecl.declarationEnd - fieldDecl.declarationSourceStart + 1);
Type type = convertType(fieldDecl.type);
setTypeForField(fieldDeclaration, type, variableDeclarationFragment.getExtraDimensions());
setModifiers(fieldDeclaration, fieldDecl);
- convert(fieldDecl.javadoc, fieldDeclaration);
+ if (!(this.resolveBindings && binding == null)) {
+ convert(fieldDecl.javadoc, fieldDeclaration);
+ }
return fieldDeclaration;
}
@@ -2777,7 +2815,13 @@
name.internalSetIdentifier(new String(localDeclaration.name));
name.setSourceRange(localDeclaration.sourceStart, localDeclaration.sourceEnd - localDeclaration.sourceStart + 1);
variableDeclarationFragment.setName(name);
- int end = retrievePositionBeforeNextCommaOrSemiColon(localDeclaration.sourceEnd, this.compilationUnitSource.length);
+ int start = localDeclaration.sourceEnd;
+ if (localDeclaration.initialization != null) {
+ final Expression expression = convert(localDeclaration.initialization);
+ variableDeclarationFragment.setInitializer(expression);
+ start = expression.getStartPosition() + expression.getLength();
+ }
+ int end = retrievePositionBeforeNextCommaOrSemiColon(start, localDeclaration.declarationSourceEnd);
if (end == -1) {
if (localDeclaration.initialization != null) {
variableDeclarationFragment.setSourceRange(localDeclaration.sourceStart, localDeclaration.initialization.sourceEnd - localDeclaration.sourceStart + 1);
@@ -2787,10 +2831,7 @@
} else {
variableDeclarationFragment.setSourceRange(localDeclaration.sourceStart, end - localDeclaration.sourceStart + 1);
}
- if (localDeclaration.initialization != null) {
- variableDeclarationFragment.setInitializer(convert(localDeclaration.initialization));
- }
- variableDeclarationFragment.setExtraDimensions(retrieveExtraDimension(localDeclaration.sourceEnd + 1, this.compilationUnitSource.length));
+ variableDeclarationFragment.setExtraDimensions(retrieveExtraDimension(localDeclaration.sourceEnd + 1, this.compilationUnitSourceLength));
if (this.resolveBindings) {
recordNodes(variableDeclarationFragment, localDeclaration);
recordNodes(name, localDeclaration);
@@ -2820,11 +2861,15 @@
final Wildcard wildcard = (Wildcard) typeReference;
final WildcardType wildcardType = new WildcardType(this.ast);
if (wildcard.bound != null) {
- wildcardType.setBound(convertType(wildcard.bound), wildcard.kind == Wildcard.EXTENDS);
+ final Type bound = convertType(wildcard.bound);
+ wildcardType.setBound(bound, wildcard.kind == Wildcard.EXTENDS);
+ int start = wildcard.sourceStart;
+ wildcardType.setSourceRange(start, bound.getStartPosition() + bound.getLength() - start);
+ } else {
+ final int start = wildcard.sourceStart;
+ final int end = wildcard.sourceEnd;
+ wildcardType.setSourceRange(start, end - start + 1);
}
- int start = wildcard.sourceStart;
- int end = wildcard.sourceEnd;
- wildcardType.setSourceRange(start, end - start + 1);
if (this.resolveBindings) {
recordNodes(wildcardType, typeReference);
}
@@ -3069,7 +3114,7 @@
if (this.resolveBindings) {
completeRecord((ArrayType) type, typeReference);
}
- int end = retrieveEndOfDimensionsPosition(sourceStart+length, this.compilationUnitSource.length);
+ int end = retrieveEndOfDimensionsPosition(sourceStart+length, this.compilationUnitSourceLength);
if (end != -1) {
type.setSourceRange(sourceStart, end - sourceStart + 1);
} else {
@@ -3637,7 +3682,7 @@
* @return int the dimension found, -1 if none
*/
protected int retrieveClosingAngleBracketPosition(int start) {
- this.scanner.resetTo(start, this.scanner.eofPosition);
+ this.scanner.resetTo(start, this.compilationUnitSourceLength);
this.scanner.returnOnlyGreater = true;
try {
int token;
@@ -3665,7 +3710,7 @@
int start = node.getStartPosition();
int length = node.getLength();
int end = start + length;
- this.scanner.resetTo(end, this.compilationUnitSource.length);
+ this.scanner.resetTo(end, this.compilationUnitSourceLength);
try {
int token;
while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
@@ -3812,6 +3857,7 @@
case TerminalTokens.TokenNameint:
case TerminalTokens.TokenNamelong:
case TerminalTokens.TokenNameshort:
+ case TerminalTokens.TokenNameboolean:
return this.scanner.currentPosition - 1;
}
}
@@ -3856,14 +3902,15 @@
int token;
while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
switch(token) {
- case TerminalTokens.TokenNameRBRACKET://166
+ case TerminalTokens.TokenNameLBRACKET:
+ case TerminalTokens.TokenNameCOMMENT_BLOCK:
+ case TerminalTokens.TokenNameCOMMENT_JAVADOC:
+ case TerminalTokens.TokenNameCOMMENT_LINE:
+ break;
+ case TerminalTokens.TokenNameRBRACKET://166
dimensions++;
break;
- case TerminalTokens.TokenNameLBRACE ://90
- case TerminalTokens.TokenNameCOMMA ://90
- case TerminalTokens.TokenNameEQUAL ://167
- case TerminalTokens.TokenNameSEMICOLON ://64
- case TerminalTokens.TokenNameRPAREN : //86
+ default:
return dimensions;
}
}
@@ -3953,7 +4000,7 @@
}
protected int retrieveProperRightBracketPosition(int bracketNumber, int start) {
- this.scanner.resetTo(start, this.compilationUnitSource.length);
+ this.scanner.resetTo(start, this.compilationUnitSourceLength);
try {
int token, count = 0;
while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
@@ -4043,7 +4090,7 @@
int length = node.getLength();
int end = start + length;
int count = 0;
- this.scanner.resetTo(end, this.compilationUnitSource.length);
+ this.scanner.resetTo(end, this.compilationUnitSourceLength);
try {
int token;
while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
@@ -4140,7 +4187,6 @@
try {
int token;
int indexInAnnotations = 0;
- int eofPosition = this.scanner.eofPosition;
while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
IExtendedModifier modifier = null;
switch(token) {
@@ -4182,7 +4228,7 @@
if (annotations != null && indexInAnnotations < annotations.length) {
org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
modifier = convert(annotation);
- this.scanner.resetTo(annotation.declarationSourceEnd + 1, eofPosition);
+ this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
}
break;
case TerminalTokens.TokenNameCOMMENT_BLOCK :
@@ -4207,6 +4253,20 @@
this.setModifiers(enumDeclaration, enumDeclaration2.annotations);
}
+ protected void setModifiers(EnumConstantDeclaration enumConstantDeclaration, org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
+ switch(this.ast.apiLevel) {
+ case AST.JLS2_INTERNAL :
+ enumConstantDeclaration.internalSetModifiers(fieldDeclaration.modifiers & CompilerModifiers.AccJustFlag);
+ if (fieldDeclaration.annotations != null) {
+ enumConstantDeclaration.setFlags(enumConstantDeclaration.getFlags() | ASTNode.MALFORMED);
+ }
+ break;
+ case AST.JLS3 :
+ this.scanner.resetTo(fieldDeclaration.declarationSourceStart, fieldDeclaration.sourceStart);
+ this.setModifiers(enumConstantDeclaration, fieldDeclaration.annotations);
+ }
+ }
+
/**
* @param fieldDeclaration
* @param fieldDecl
@@ -4319,8 +4379,15 @@
if (annotations != null && indexInAnnotations < annotations.length) {
org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
modifier = convert(annotation);
- this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.scanner.eofPosition);
+ this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
}
+ break;
+ case TerminalTokens.TokenNameCOMMENT_BLOCK :
+ case TerminalTokens.TokenNameCOMMENT_LINE :
+ case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+ break;
+ default :
+ return;
}
if (modifier != null) {
variableDecl.modifiers().add(modifier);
@@ -4387,8 +4454,15 @@
if (annotations != null && indexInAnnotations < annotations.length) {
org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
modifier = convert(annotation);
- this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.scanner.eofPosition);
+ this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
}
+ break;
+ case TerminalTokens.TokenNameCOMMENT_BLOCK :
+ case TerminalTokens.TokenNameCOMMENT_LINE :
+ case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+ break;
+ default :
+ return;
}
if (modifier != null) {
variableDecl.modifiers().add(modifier);
@@ -4482,8 +4556,15 @@
if (annotations != null && indexInAnnotations < annotations.length) {
org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
modifier = convert(annotation);
- this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.scanner.eofPosition);
+ this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
}
+ break;
+ case TerminalTokens.TokenNameCOMMENT_BLOCK :
+ case TerminalTokens.TokenNameCOMMENT_LINE :
+ case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+ break;
+ default :
+ return;
}
if (modifier != null) {
variableDeclarationExpression.modifiers().add(modifier);
@@ -4556,8 +4637,15 @@
if (annotations != null && indexInAnnotations < annotations.length) {
org.eclipse.jdt.internal.compiler.ast.Annotation annotation = annotations[indexInAnnotations++];
modifier = convert(annotation);
- this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.scanner.eofPosition);
+ this.scanner.resetTo(annotation.declarationSourceEnd + 1, this.compilationUnitSourceLength);
}
+ break;
+ case TerminalTokens.TokenNameCOMMENT_BLOCK :
+ case TerminalTokens.TokenNameCOMMENT_LINE :
+ case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+ break;
+ default :
+ return;
}
if (modifier != null) {
variableDeclarationStatement.modifiers().add(modifier);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
index ba7e715..88dc2ef 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
@@ -224,13 +224,28 @@
/**
* Sets the compiler options to be used when parsing.
- * <p>
- * The compiler options default to {@link JavaCore#getOptions()}.
- * </p>
+ * <p>
+ * Note that {@link #setSource(IClassFile)},
+ * {@link #setSource(ICompilationUnit)},
+ * and {@link #setProject(IJavaProject)} reset the compiler options
+ * based on the Java project. In other cases, compiler options default
+ * to {@link JavaCore#getOptions()}. In either case, and especially
+ * in the latter, the caller should carefully weight the consequences of
+ * allowing compiler options to be defaulted as opposed to being
+ * explicitly specified for the <code>ASTParser</code> instance.
+ * For instance, there is a compiler option called "Source Compatibility Mode"
+ * which determines which JDK level the source code is expected to meet.
+ * If you specify "1.4", then "assert" is treated as a keyword and disallowed
+ * as an identifier; if you specify "1.3", then "assert" is allowed as an
+ * identifier. So this particular setting has a major bearing on what is
+ * considered syntactically legal. By explicitly specifying the setting,
+ * the client control exactly how the parser works. On the other hand,
+ * allowing default settings means the parsing behaves like other JDT tools.
+ * </p>
*
* @param options the table of options (key type: <code>String</code>;
* value type: <code>String</code>), or <code>null</code>
- * to set it back to the default
+ * to set it back to the default
*/
public void setCompilerOptions(Map options) {
if (options == null) {
@@ -522,21 +537,24 @@
}
/**
- * Sets the Java project used when resolving bindings.
- * This method automatically sets the compiler
- * options based on the given project:
- * <pre>
- * setCompilerOptions(project.getOptions(true));
- * </pre>
- * This setting is used in conjunction with <code>setSource(char[])</code>.
- * For the purposes of resolving bindings, types declared in the
+ * Sets the Java project used when resolving bindings.
+ * This method automatically sets the compiler
+ * options based on the given project:
+ * <pre>
+ * setCompilerOptions(project.getOptions(true));
+ * </pre>
+ * See {@link #setCompilerOptions(Map)} for a discussion of
+ * the pros and cons of using these options vs specifying
+ * compiler options explicitly.
+ * This setting is used in conjunction with <code>setSource(char[])</code>.
+ * For the purposes of resolving bindings, types declared in the
* source string will hide types by the same name available
- * through the classpath of the given project.
- * Defaults to none (<code>null</code>).
- *
+ * through the classpath of the given project.
+ * Defaults to none (<code>null</code>).
+ *
* @param project the Java project used to resolve names, or
* <code>null</code> if none
- */
+ */
public void setProject(IJavaProject project) {
this.project = project;
if (project != null) {
@@ -870,8 +888,9 @@
* @see ASTNode#getLength()
*/
private ASTNode internalCreateASTForKind() {
- ASTConverter converter = new ASTConverter(this.compilerOptions, false, null);
+ final ASTConverter converter = new ASTConverter(this.compilerOptions, false, null);
converter.compilationUnitSource = this.rawSource;
+ converter.compilationUnitSourceLength = this.rawSource.length;
converter.scanner.setSource(this.rawSource);
AST ast = AST.newAST(this.apiLevel);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
index fbd5b2e..c97210d 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.jdt.core.dom;
+import java.util.HashSet;
+
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.env.IConstants;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
@@ -61,21 +63,21 @@
* @param declaringElement2
* @return true if both parameters are equals, false otherwise
*/
- static boolean isEqual(Binding declaringElement, Binding declaringElement2, boolean checkTypeVariables) {
+ static boolean isEqual(Binding declaringElement, Binding declaringElement2, HashSet visitedTypes) {
if (declaringElement instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
if (!(declaringElement2 instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding)){
return false;
}
return isEqual((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaringElement,
(org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaringElement2,
- checkTypeVariables);
+ visitedTypes);
} else if (declaringElement instanceof org.eclipse.jdt.internal.compiler.lookup.MethodBinding) {
if (!(declaringElement2 instanceof org.eclipse.jdt.internal.compiler.lookup.MethodBinding)) {
return false;
}
return isEqual((org.eclipse.jdt.internal.compiler.lookup.MethodBinding) declaringElement,
(org.eclipse.jdt.internal.compiler.lookup.MethodBinding) declaringElement2,
- checkTypeVariables);
+ visitedTypes);
} else if (declaringElement instanceof VariableBinding) {
if (!(declaringElement2 instanceof VariableBinding)) {
return false;
@@ -104,23 +106,19 @@
static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding,
org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding2) {
- return isEqual(methodBinding, methodBinding2, true);
+ return isEqual(methodBinding, methodBinding2, new HashSet());
}
static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding,
org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding2,
- boolean checkTypeVariables) {
- if (checkTypeVariables) {
- if (!isEqual(methodBinding.typeVariables, methodBinding2.typeVariables, true)
- || !isEqual(methodBinding.parameters, methodBinding2.parameters, true)) {
- return false;
- }
- }
+ HashSet visitedTypes) {
return (methodBinding == null && methodBinding2 == null)
|| (CharOperation.equals(methodBinding.selector, methodBinding2.selector)
- && isEqual(methodBinding.returnType, methodBinding2.returnType, checkTypeVariables)
- && isEqual(methodBinding.thrownExceptions, methodBinding2.thrownExceptions, checkTypeVariables)
- && isEqual(methodBinding.declaringClass, methodBinding2.declaringClass, true));
+ && isEqual(methodBinding.returnType, methodBinding2.returnType, visitedTypes)
+ && isEqual(methodBinding.thrownExceptions, methodBinding2.thrownExceptions, visitedTypes)
+ && isEqual(methodBinding.declaringClass, methodBinding2.declaringClass, visitedTypes)
+ && isEqual(methodBinding.typeVariables, methodBinding2.typeVariables, visitedTypes)
+ && isEqual(methodBinding.parameters, methodBinding2.parameters, visitedTypes));
}
static boolean isEqual(VariableBinding variableBinding, VariableBinding variableBinding2) {
@@ -131,10 +129,11 @@
}
static boolean isEqual(FieldBinding fieldBinding, FieldBinding fieldBinding2) {
+ HashSet visitedTypes = new HashSet();
return (fieldBinding.modifiers & CompilerModifiers.AccJustFlag) == (fieldBinding2.modifiers & CompilerModifiers.AccJustFlag)
&& CharOperation.equals(fieldBinding.name, fieldBinding2.name)
- && isEqual(fieldBinding.type, fieldBinding2.type, true)
- && isEqual(fieldBinding.declaringClass, fieldBinding2.declaringClass, true);
+ && isEqual(fieldBinding.type, fieldBinding2.type, visitedTypes)
+ && isEqual(fieldBinding.declaringClass, fieldBinding2.declaringClass, visitedTypes);
}
/**
@@ -143,14 +142,14 @@
* @return true if both parameters are equals, false otherwise
*/
static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] bindings, org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] otherBindings) {
- return isEqual(bindings, otherBindings, true);
+ return isEqual(bindings, otherBindings, new HashSet());
}
/**
* @param bindings
* @param otherBindings
* @return true if both parameters are equals, false otherwise
*/
- static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] bindings, org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] otherBindings, boolean checkTypeVariables) {
+ static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] bindings, org.eclipse.jdt.internal.compiler.lookup.TypeBinding[] otherBindings, HashSet visitedTypes) {
if (bindings == null) {
return otherBindings == null;
} else if (otherBindings == null) {
@@ -162,20 +161,19 @@
return false;
}
for (int i = 0; i < length; i++) {
- if (!isEqual(bindings[i], otherBindings[i], checkTypeVariables)) {
+ if (!isEqual(bindings[i], otherBindings[i], visitedTypes)) {
return false;
}
}
return true;
}
}
- // TODO (olivier) should optimize to use switch(binding.kind()) & modifier bitmask comparisons
- static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding2, boolean checkTypeVariables) {
+ static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding2, HashSet visitedTypes) {
if (typeBinding == typeBinding2)
return true;
if (typeBinding == null || typeBinding2 == null)
return false;
-
+
switch (typeBinding.kind()) {
case Binding.BASE_TYPE :
if (!typeBinding2.isBaseType()) {
@@ -188,7 +186,7 @@
return false;
}
return typeBinding.dimensions() == typeBinding2.dimensions()
- && isEqual(typeBinding.leafComponentType(), typeBinding2.leafComponentType(), checkTypeVariables);
+ && isEqual(typeBinding.leafComponentType(), typeBinding2.leafComponentType(), visitedTypes);
case Binding.PARAMETERIZED_TYPE :
if (!typeBinding2.isParameterizedType()) {
@@ -196,14 +194,10 @@
}
ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) typeBinding;
ParameterizedTypeBinding parameterizedTypeBinding2 = (ParameterizedTypeBinding) typeBinding2;
- if (checkTypeVariables) {
- if (!isEqual(parameterizedTypeBinding.arguments, parameterizedTypeBinding2.arguments, false)) {
- return false;
- }
- }
return CharOperation.equals(parameterizedTypeBinding.compoundName, parameterizedTypeBinding2.compoundName)
&& (parameterizedTypeBinding.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation))
- == (parameterizedTypeBinding2.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation));
+ == (parameterizedTypeBinding2.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation))
+ && isEqual(parameterizedTypeBinding.arguments, parameterizedTypeBinding2.arguments, visitedTypes);
case Binding.WILDCARD_TYPE :
if (!typeBinding2.isWildcard()) {
@@ -211,10 +205,13 @@
}
WildcardBinding wildcardBinding = (WildcardBinding) typeBinding;
WildcardBinding wildcardBinding2 = (WildcardBinding) typeBinding2;
- return isEqual(wildcardBinding.bound, wildcardBinding2.bound, checkTypeVariables)
+ return isEqual(wildcardBinding.bound, wildcardBinding2.bound, visitedTypes)
&& wildcardBinding.boundKind == wildcardBinding2.boundKind;
case Binding.TYPE_PARAMETER :
+ if (visitedTypes.contains(typeBinding)) return true;
+ visitedTypes.add(typeBinding);
+
if (!(typeBinding2.isTypeVariable())) {
return false;
}
@@ -224,18 +221,16 @@
}
CaptureBinding captureBinding = (CaptureBinding) typeBinding;
CaptureBinding captureBinding2 = (CaptureBinding) typeBinding2;
- return isEqual(captureBinding.wildcard, captureBinding2.wildcard, checkTypeVariables);
+ return captureBinding.position == captureBinding2.position
+ && isEqual(captureBinding.wildcard, captureBinding2.wildcard, visitedTypes)
+ && isEqual(captureBinding.sourceType, captureBinding2.sourceType, visitedTypes);
}
TypeVariableBinding typeVariableBinding = (TypeVariableBinding) typeBinding;
TypeVariableBinding typeVariableBinding2 = (TypeVariableBinding) typeBinding2;
- if (checkTypeVariables) {
- return CharOperation.equals(typeVariableBinding.sourceName, typeVariableBinding2.sourceName)
- && isEqual(typeVariableBinding.declaringElement, typeVariableBinding2.declaringElement, false)
- && isEqual(typeVariableBinding.superclass(), typeVariableBinding2.superclass(), true)
- && isEqual(typeVariableBinding.superInterfaces(), typeVariableBinding2.superInterfaces(), true);
- } else {
- return CharOperation.equals(typeVariableBinding.sourceName, typeVariableBinding2.sourceName);
- }
+ return CharOperation.equals(typeVariableBinding.sourceName, typeVariableBinding2.sourceName)
+ && isEqual(typeVariableBinding.declaringElement, typeVariableBinding2.declaringElement, visitedTypes)
+ && isEqual(typeVariableBinding.superclass(), typeVariableBinding2.superclass(), visitedTypes)
+ && isEqual(typeVariableBinding.superInterfaces(), typeVariableBinding2.superInterfaces(), visitedTypes);
case Binding.GENERIC_TYPE :
if (!typeBinding2.isGenericType()) {
@@ -243,14 +238,10 @@
}
ReferenceBinding referenceBinding = (ReferenceBinding) typeBinding;
ReferenceBinding referenceBinding2 = (ReferenceBinding) typeBinding2;
- if (checkTypeVariables) {
- if (!isEqual(referenceBinding.typeVariables(), referenceBinding2.typeVariables(), true)) {
- return false;
- }
- }
return CharOperation.equals(referenceBinding.compoundName, referenceBinding2.compoundName)
&& (referenceBinding.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation))
- == (referenceBinding2.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation));
+ == (referenceBinding2.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation))
+ && isEqual(referenceBinding.typeVariables(), referenceBinding2.typeVariables(), visitedTypes);
case Binding.RAW_TYPE :
default :
@@ -274,6 +265,6 @@
* @return true if both parameters are equals, false otherwise
*/
static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding2) {
- return isEqual(typeBinding, typeBinding2, true);
+ return isEqual(typeBinding, typeBinding2, new HashSet());
}
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java
index 8463185..90b390b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java
@@ -445,7 +445,7 @@
* deprecation warnings.
* @since 3.1
*/
- /*package*/ public void internalSetName(Name name) {
+ /*package*/ void internalSetName(Name name) {
supportedOnlyIn2();
if (name == null) {
throw new IllegalArgumentException();
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java
index 5306d06..b8f0cd5 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java
@@ -380,7 +380,7 @@
* a <code>VariableDeclarationFragment</code> in a
* <code>VariableDeclarationStatement</code> or
* <code>VariableDeclarationExpression</code></li>
- * <li>methods - a <code>MethodDeclaration</code> </li>
+ * <li>method - a <code>MethodDeclaration</code> </li>
* <li>constructor - a <code>MethodDeclaration</code> </li>
* <li>annotation type - an <code>AnnotationTypeDeclaration</code></li>
* <li>annotation type member - an <code>AnnotationTypeMemberDeclaration</code></li>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
index 3e5898d..17828bb 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
@@ -16,6 +16,7 @@
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
@@ -85,6 +86,8 @@
DefaultBindingResolver.BindingTables bindingTables;
boolean hasCompilationAborted;
+
+ private IProgressMonitor monitor;
/**
* Answer a new CompilationUnitVisitor using the given name environment and compiler options.
@@ -126,10 +129,12 @@
IErrorHandlingPolicy policy,
Map settings,
ICompilerRequestor requestor,
- IProblemFactory problemFactory) {
+ IProblemFactory problemFactory,
+ IProgressMonitor monitor) {
super(environment, policy, settings, requestor, problemFactory, false);
this.hasCompilationAborted = false;
+ this.monitor =monitor;
}
/*
@@ -181,6 +186,7 @@
this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
addCompilationUnit(sourceUnit, parsedUnit);
this.requestedSources.put(unitResult.getFileName(), sourceUnit);
+ worked(1);
} finally {
sourceUnits[i] = null; // no longer hold onto the unit
}
@@ -207,16 +213,12 @@
}
} else {
- if (!resolver.hasTypeName()) {
- // package binding key
- char[] pkgName = CharOperation.concatWith(resolver.compoundName(), '.');
- this.requestedKeys.put(pkgName, resolver);
- } else {
- // base type binding or binary binding
- char[] key = resolver.getKey().toCharArray();
- this.requestedKeys.put(key, resolver);
- }
+ char[] key = resolver.hasTypeName()
+ ? resolver.getKey().toCharArray() // binary binding
+ : CharOperation.concatWith(resolver.compoundName(), '.'); // package binding or base type binding
+ this.requestedKeys.put(key, resolver);
}
+ worked(1);
}
// binding resolution
@@ -319,40 +321,47 @@
}
public static void parse(ICompilationUnit[] compilationUnits, ASTRequestor astRequestor, int apiLevel, Map options, IProgressMonitor monitor) {
- CompilerOptions compilerOptions = new CompilerOptions(options);
- Parser parser = new CommentRecorderParser(
- new ProblemReporter(
- DefaultErrorHandlingPolicies.proceedWithAllProblems(),
- compilerOptions,
- new DefaultProblemFactory()),
- false);
- for (int i = 0, length = compilationUnits.length; i < length; i++) {
- org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) compilationUnits[i];
- CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit);
- CompilationUnitDeclaration compilationUnitDeclaration = parser.dietParse(sourceUnit, compilationResult);
-
- if (compilationUnitDeclaration.ignoreMethodBodies) {
- compilationUnitDeclaration.ignoreFurtherInvestigation = true;
- // if initial diet parse did not work, no need to dig into method bodies.
- continue;
+ try {
+ CompilerOptions compilerOptions = new CompilerOptions(options);
+ Parser parser = new CommentRecorderParser(
+ new ProblemReporter(
+ DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+ compilerOptions,
+ new DefaultProblemFactory()),
+ false);
+ int length = compilationUnits.length;
+ if (monitor != null) monitor.beginTask("", length); //$NON-NLS-1$
+ for (int i = 0; i < length; i++) {
+ org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) compilationUnits[i];
+ CompilationResult compilationResult = new CompilationResult(sourceUnit, 0, 0, compilerOptions.maxProblemsPerUnit);
+ CompilationUnitDeclaration compilationUnitDeclaration = parser.dietParse(sourceUnit, compilationResult);
+
+ if (compilationUnitDeclaration.ignoreMethodBodies) {
+ compilationUnitDeclaration.ignoreFurtherInvestigation = true;
+ // if initial diet parse did not work, no need to dig into method bodies.
+ continue;
+ }
+
+ //fill the methods bodies in order for the code to be generated
+ //real parse of the method....
+ parser.scanner.setSource(compilationResult);
+ org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types;
+ if (types != null) {
+ for (int j = types.length; --j >= 0;)
+ types[j].parseMethod(parser, compilationUnitDeclaration);
+ }
+
+ // convert AST
+ CompilationUnit node = convert(compilationUnitDeclaration, sourceUnit.getContents(), apiLevel, options, false/*don't resolve binding*/, null/*no owner needed*/, null/*no binding table needed*/, monitor);
+ node.setJavaElement(compilationUnits[i]);
+
+ // accept AST
+ astRequestor.acceptAST(compilationUnits[i], node);
+
+ if (monitor != null) monitor.worked(1);
}
-
- //fill the methods bodies in order for the code to be generated
- //real parse of the method....
- parser.scanner.setSource(compilationResult);
- org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types;
- if (types != null) {
- for (int j = types.length; --j >= 0;)
- types[j].parseMethod(parser, compilationUnitDeclaration);
- }
-
- // convert AST
- CompilationUnit node = convert(compilationUnitDeclaration, sourceUnit.getContents(), apiLevel, options, false/*don't resolve binding*/, null/*no owner needed*/, null/*no binding table needed*/, monitor);
- node.setJavaElement(compilationUnits[i]);
-
-
- // accept AST
- astRequestor.acceptAST(compilationUnits[i], node);
+ } finally {
+ if (monitor != null) monitor.done();
}
}
@@ -428,6 +437,10 @@
CancelableNameEnvironment environment = null;
CancelableProblemFactory problemFactory = null;
try {
+ if (monitor != null) {
+ int amountOfWork = (compilationUnits.length + bindingKeys.length) * 2; // 1 for beginToCompile, 1 for resolve
+ monitor.beginTask("", amountOfWork); //$NON-NLS-1$
+ }
environment = new CancelableNameEnvironment(((JavaProject) javaProject), owner, monitor);
problemFactory = new CancelableProblemFactory(monitor);
CompilationUnitResolver resolver =
@@ -436,9 +449,10 @@
getHandlingPolicy(),
options,
getRequestor(),
- problemFactory);
+ problemFactory,
+ monitor);
- resolver.resolve(compilationUnits, bindingKeys, requestor, apiLevel, options, owner, monitor);
+ resolver.resolve(compilationUnits, bindingKeys, requestor, apiLevel, options, owner);
if (NameLookup.VERBOSE) {
System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -447,6 +461,7 @@
// project doesn't exist -> simple parse without resolving
parse(compilationUnits, requestor, apiLevel, options, monitor);
} finally {
+ if (monitor != null) monitor.done();
if (environment != null) {
environment.monitor = null; // don't hold a reference to this external object
}
@@ -476,7 +491,8 @@
getHandlingPolicy(),
options,
getRequestor(),
- problemFactory);
+ problemFactory,
+ monitor);
unit =
resolver.resolve(
@@ -631,7 +647,7 @@
}
}
- private void resolve(ICompilationUnit[] compilationUnits, String[] bindingKeys, ASTRequestor astRequestor, int apiLevel, Map compilerOptions, WorkingCopyOwner owner, IProgressMonitor monitor) {
+ private void resolve(ICompilationUnit[] compilationUnits, String[] bindingKeys, ASTRequestor astRequestor, int apiLevel, Map compilerOptions, WorkingCopyOwner owner) {
// temporararily connect ourselves to the ASTResolver - must disconnect when done
astRequestor.compilationUnitResolver = this;
@@ -653,7 +669,7 @@
if (this.requestedKeys.containsKey(fileName) || this.requestedSources.containsKey(fileName)) {
super.process(unit, i); // this.process(...) is optimized to not process already known units
- ICompilationUnit source = (ICompilationUnit) this.requestedSources.removeKey(fileName);
+ ICompilationUnit source = (ICompilationUnit) this.requestedSources.get(fileName);
if (source != null) {
// convert AST
CompilationResult compilationResult = unit.compilationResult;
@@ -661,7 +677,7 @@
char[] contents = sourceUnit.getContents();
AST ast = AST.newAST(apiLevel);
ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
- ASTConverter converter = new ASTConverter(compilerOptions, true/*need to resolve bindings*/, monitor);
+ ASTConverter converter = new ASTConverter(compilerOptions, true/*need to resolve bindings*/, this.monitor);
BindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables);
ast.setBindingResolver(resolver);
converter.setAST(ast);
@@ -673,17 +689,25 @@
// pass it to requestor
astRequestor.acceptAST(source, compilationUnit);
+
+ worked(1);
}
- Object key = this.requestedKeys.removeKey(fileName);
+ Object key = this.requestedKeys.get(fileName);
if (key instanceof BindingKeyResolver) {
reportBinding(key, astRequestor, owner, unit);
+ worked(1);
} else if (key instanceof ArrayList) {
Iterator iterator = ((ArrayList) key).iterator();
while (iterator.hasNext()) {
reportBinding(iterator.next(), astRequestor, owner, unit);
+ worked(1);
}
}
+
+ // remove at the end so that we don't resolve twice if a source and a key for the same file name have been requested
+ this.requestedSources.removeKey(fileName);
+ this.requestedKeys.removeKey(fileName);
} else {
if (unit.scope != null)
unit.scope.faultInTypes(); // still force resolution of signatures, so clients can query DOM AST
@@ -706,7 +730,10 @@
IBinding binding = compilerBinding == null ? null : resolver.getBinding(compilerBinding);
// pass it to requestor
astRequestor.acceptBinding(((BindingKeyResolver) this.requestedKeys.valueTable[j]).getKey(), binding);
+ worked(1);
}
+ } catch (OperationCanceledException e) {
+ throw e;
} catch (AbortCompilation e) {
this.handleInternalException(e, unit);
} catch (Error e) {
@@ -857,4 +884,12 @@
analyzeCode,
generateCode);
}
+
+ private void worked(int work) {
+ if (this.monitor != null) {
+ if (this.monitor.isCanceled())
+ throw new OperationCanceledException();
+ this.monitor.worked(work);
+ }
+ }
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
index 710b694..fd3e24b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
@@ -281,7 +281,7 @@
case ProblemReasons.NonStaticReferenceInStaticContext :
if (referenceBinding instanceof ProblemReferenceBinding) {
ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) referenceBinding;
- Binding binding2 = problemReferenceBinding.original;
+ Binding binding2 = problemReferenceBinding.closestMatch;
if (binding2 != null && binding2 instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
TypeBinding binding = (TypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(binding2);
if (binding != null) {
@@ -310,13 +310,15 @@
synchronized IVariableBinding getVariableBinding(org.eclipse.jdt.internal.compiler.lookup.VariableBinding variableBinding) {
if (variableBinding != null) {
if (variableBinding.isValidBinding()) {
- IVariableBinding binding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(variableBinding);
- if (binding != null) {
+ if (variableBinding.type != null) {
+ IVariableBinding binding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(variableBinding);
+ if (binding != null) {
+ return binding;
+ }
+ binding = new VariableBinding(this, variableBinding);
+ this.bindingTables.compilerBindingsToASTBindings.put(variableBinding, binding);
return binding;
- }
- binding = new VariableBinding(this, variableBinding);
- this.bindingTables.compilerBindingsToASTBindings.put(variableBinding, binding);
- return binding;
+ }
} else {
/*
* http://dev.eclipse.org/bugs/show_bug.cgi?id=24449
@@ -956,13 +958,15 @@
if (declaringClass != null) {
FieldBinding exactBinding = declaringClass.getField(tokens[tokens.length - 1], true /*resolve*/);
if (exactBinding != null) {
- IVariableBinding variableBinding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
- if (variableBinding != null) {
+ if (exactBinding.type != null) {
+ IVariableBinding variableBinding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
+ if (variableBinding != null) {
+ return variableBinding;
+ }
+ variableBinding = new VariableBinding(this, exactBinding);
+ this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding);
return variableBinding;
}
- variableBinding = new VariableBinding(this, exactBinding);
- this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding);
- return variableBinding;
}
}
break;
@@ -1101,13 +1105,15 @@
ReferenceBinding declaringClass = problemFieldBinding.declaringClass;
FieldBinding exactBinding = declaringClass.getField(problemFieldBinding.name, true /*resolve*/);
if (exactBinding != null) {
- IVariableBinding variableBinding2 = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
- if (variableBinding2 != null) {
+ if (exactBinding.type != null) {
+ IVariableBinding variableBinding2 = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
+ if (variableBinding2 != null) {
+ return variableBinding2;
+ }
+ variableBinding2 = new VariableBinding(this, exactBinding);
+ this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding2);
return variableBinding2;
}
- variableBinding2 = new VariableBinding(this, exactBinding);
- this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding2);
- return variableBinding2;
}
break;
}
@@ -1486,9 +1492,9 @@
} else if ("java.lang.Exception".equals(name)) {//$NON-NLS-1$
return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_EXCEPTION, 3));
} else if ("java.lang.RuntimeException".equals(name)) {//$NON-NLS-1$
- return this.getTypeBinding(this.scope.getJavaLangRuntimeException());
+ return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION, 3));
} else if ("java.lang.Error".equals(name)) {//$NON-NLS-1$
- return this.getTypeBinding(this.scope.getJavaLangError());
+ return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_ERROR, 3));
} else if ("java.lang.Class".equals(name)) {//$NON-NLS-1$
return this.getTypeBinding(this.scope.getJavaLangClass());
} else if ("java.lang.Cloneable".equals(name)) {//$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
index 7e0e506..80c9b23 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
@@ -146,11 +146,16 @@
* classes) is the innermost class or interface containing the expression
* or statement in which this type is declared.
* </p>
- * <p>The declaring class of a type variable is the class in which the type variable
- * is declared if it is declared on a type. It returns <code>null</code> otherwise.
+ * <p>The declaring class of a type variable is the class in which the type
+ * variable is declared if it is declared on a type. It returns
+ * <code>null</code> otherwise.
+ * </p>
+ * <p>The declaring class of a capture binding is the innermost class or
+ * interface containing the expression or statement in which this capture is
+ * declared.
* </p>
* <p>Array types, primitive types, the null type, top-level types,
- * wildcard types, and capture bindings have no declaring class.
+ * wildcard types have no declaring class.
* </p>
*
* @return the binding of the type that declares this type, or
@@ -178,6 +183,7 @@
*
* @return the binding of the method that declares this type, or
* <code>null</code> if none
+ * @since 3.1
*/
public IMethodBinding getDeclaringMethod();
@@ -215,7 +221,11 @@
* if it has bounds and java.lang.Object if it does not.</li>
* <li>For captures ({@link #isCapture()})
* - returns the binding for the erasure of the leftmost bound
- * if it has bounds and java.lang.Object if it does not.</li>
+ * if it has bounds and java.lang.Object if it does not.</li>
+ * <li>For array types ({@link #isArray()}) - returns an array type of
+ * the same dimension ({@link #getDimensions()}) as this type
+ * binding for which the element type is the erasure of the element type
+ * ({@link #getElementType()}) of this type binding.</li>
* <li>For all other type bindings - returns the identical binding.</li>
* </ul>
*
@@ -445,11 +455,14 @@
public ITypeBinding[] getTypeArguments();
/**
- * Returns the type bounds of this type variable or capture.
+ * Returns the declared type bounds of this type variable or capture. If the
+ * variable or the capture had no explicit bound, then it returns an empty list.
* <p>
- * Note that the first type bound is always a class type. If the type
- * variable does not explicitly declare a class type bound, the first
- * type bound will be the binding for <code>java.lang.Object</code>.
+ * Note that per construction, it can only contain one class or array type,
+ * at most, and then it is located in first position.
+ * </p>
+ * Also note that array type bound may only occur in the case of a capture
+ * binding, e.g. <code>capture-of ? extends Object[]</code>
* </p>
*
* @return the list of type bindings for this type variable or capture,
@@ -581,7 +594,11 @@
* Returns whether this type is cast compatible with the given type,
* as specified in section 5.5 of <em>The Java Language
* Specification, Third Edition</em> (JLS3).
- *
+ * <p>
+ * NOTE: The cast compatibility check performs backwards.
+ * When testing whether type B can be cast to type A, one would use:
+ * <code>A.isCastCompatible(B)</code>
+ * </p>
* @param type the type to check compatibility against
* @return <code>true</code> if this type is cast compatible with the
* given type, and <code>false</code> otherwise
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
index 6b20808..1d6b034 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
@@ -209,7 +209,17 @@
void postCloneNodeEvent(ASTNode node, ASTNode clone) {
- this.clonedNodes.put(clone, node);
+ if(node.ast == root.ast && clone.ast == root.ast) {
+ if((node.getFlags() & ASTNode.ORIGINAL) != 0) {
+ this.clonedNodes.put(clone, node);
+ } else {
+ // node can be a cloned node
+ Object original = this.clonedNodes.get(node);
+ if(original != null) {
+ this.clonedNodes.put(clone, original);
+ }
+ }
+ }
this.cloneDepth--;
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
index 7ed6eb1..c0b6804 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
@@ -28,6 +28,7 @@
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.Member;
import org.eclipse.jdt.internal.core.util.Util;
@@ -155,8 +156,15 @@
}
return this.exceptionTypes;
}
-
+
public IJavaElement getJavaElement() {
+ JavaElement element = getUnresolvedJavaElement();
+ if (element == null)
+ return null;
+ return element.resolved(this.binding);
+ }
+
+ private JavaElement getUnresolvedJavaElement() {
IType declaringType = (IType) getDeclaringClass().getJavaElement();
if (declaringType == null) return null;
if (!(this.resolver instanceof DefaultBindingResolver)) return null;
@@ -171,20 +179,22 @@
Type type = parameter.getType();
String typeSig = Util.getSignature(type);
int arrayDim = parameter.getExtraDimensions();
- if (parameter.isVarargs())
+ if (parameter.getAST().apiLevel() >= AST.JLS3 && parameter.isVarargs()) {
arrayDim++;
- if (arrayDim > 0)
+ }
+ if (arrayDim > 0) {
typeSig = Signature.createArraySignature(typeSig, arrayDim);
+ }
parameterSignatures.add(typeSig);
}
int parameterCount = parameterSignatures.size();
String[] parameters = new String[parameterCount];
parameterSignatures.toArray(parameters);
- return declaringType.getMethod(getName(), parameters);
+ return (JavaElement) declaringType.getMethod(getName(), parameters);
} else {
// annotation type member declaration
AnnotationTypeMemberDeclaration typeMemberDeclaration = (AnnotationTypeMemberDeclaration) node;
- return declaringType.getMethod(typeMemberDeclaration.getName().getIdentifier(), new String[0]); // annotation type members don't have parameters
+ return (JavaElement) declaringType.getMethod(typeMemberDeclaration.getName().getIdentifier(), new String[0]); // annotation type members don't have parameters
}
} else {
// case of method not in the created AST, or a binary method
@@ -198,7 +208,7 @@
}
IMethod result = declaringType.getMethod(selector, parameterSignatures);
if (declaringType.isBinary())
- return result;
+ return (JavaElement) result;
IMethod[] methods = null;
try {
methods = declaringType.getMethods();
@@ -209,7 +219,7 @@
IMethod[] candidates = Member.findMethods(result, methods);
if (candidates == null || candidates.length == 0)
return null;
- return candidates[0];
+ return (JavaElement) candidates[0];
}
}
@@ -379,16 +389,25 @@
/* (non-Javadoc)
* @see IMethodBinding#overrides(IMethodBinding)
*/
- public boolean overrides(IMethodBinding method) {
- org.eclipse.jdt.internal.compiler.lookup.MethodBinding otherCompilerBinding = ((MethodBinding) method).binding;
- if (this.binding == otherCompilerBinding)
+ public boolean overrides(IMethodBinding overridenMethod) {
+ org.eclipse.jdt.internal.compiler.lookup.MethodBinding overridenCompilerBinding = ((MethodBinding) overridenMethod).binding;
+ if (this.binding == overridenCompilerBinding)
return false;
- if (!this.binding.declaringClass.isCompatibleWith(otherCompilerBinding.declaringClass))
+ if (!CharOperation.equals(this.binding.selector, overridenCompilerBinding.selector))
return false;
- LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
- if (lookupEnvironment == null) return false;
- MethodVerifier methodVerifier = lookupEnvironment.methodVerifier();
- return methodVerifier.doesMethodOverride(this.binding, otherCompilerBinding);
+ ReferenceBinding match = this.binding.declaringClass.findSuperTypeWithSameErasure(overridenCompilerBinding.declaringClass);
+ if (match == null) return false;
+
+ org.eclipse.jdt.internal.compiler.lookup.MethodBinding[] superMethods = match.methods();
+ for (int i = 0, length = superMethods.length; i < length; i++) {
+ if (superMethods[i].original() == overridenCompilerBinding) {
+ LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
+ if (lookupEnvironment == null) return false;
+ MethodVerifier methodVerifier = lookupEnvironment.methodVerifier();
+ return methodVerifier.doesMethodOverride(this.binding, superMethods[i]);
+ }
+ }
+ return false;
}
/*
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index 81c376d..66f96de 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -50,6 +50,7 @@
import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.jdt.internal.core.ClassFile;
+import org.eclipse.jdt.internal.core.JavaElement;
/**
* Internal implementation of type bindings.
@@ -277,7 +278,7 @@
}
} else if (this.binding.isTypeVariable()) {
TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
- Binding declaringElement = typeVariableBinding.declaringElement;
+ Binding declaringElement = typeVariableBinding.isCapture() ? ((CaptureBinding) typeVariableBinding).sourceType : typeVariableBinding.declaringElement;
if (declaringElement instanceof ReferenceBinding) {
try {
return this.resolver.getTypeBinding((ReferenceBinding)declaringElement);
@@ -366,23 +367,39 @@
}
public IJavaElement getJavaElement() {
- if (this.binding == null)
+ JavaElement element = getUnresolvedJavaElement();
+ if (element == null)
return null;
- switch (this.binding.kind()) {
+ return element.resolved(this.binding);
+ }
+
+ private JavaElement getUnresolvedJavaElement() {
+ return getUnresolvedJavaElement(this.binding);
+ }
+ private JavaElement getUnresolvedJavaElement(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding ) {
+ if (typeBinding == null)
+ return null;
+ switch (typeBinding.kind()) {
case Binding.ARRAY_TYPE :
+ typeBinding = ((ArrayBinding) typeBinding).leafComponentType();
+ return getUnresolvedJavaElement(typeBinding);
case Binding.BASE_TYPE :
+ case Binding.WILDCARD_TYPE :
return null;
+ default :
+ if (typeBinding.isCapture())
+ return null;
}
ReferenceBinding referenceBinding;
- if (this.binding.isParameterizedType() || this.binding.isRawType())
- referenceBinding = (ReferenceBinding) this.binding.erasure();
+ if (typeBinding.isParameterizedType() || typeBinding.isRawType())
+ referenceBinding = (ReferenceBinding) typeBinding.erasure();
else
- referenceBinding = (ReferenceBinding) this.binding;
+ referenceBinding = (ReferenceBinding) typeBinding;
char[] fileName = referenceBinding.getFileName();
if (Util.isClassFileName(fileName)) {
ClassFile classFile = (ClassFile) getClassFile(fileName);
if (classFile == null) return null;
- return classFile.getType();
+ return (JavaElement) classFile.getType();
}
if (referenceBinding.isLocalType() || referenceBinding.isAnonymousType()) {
// local or anonymous type
@@ -393,7 +410,7 @@
ASTNode node = (ASTNode) bindingResolver.bindingsToAstNodes.get(this);
// must use getElementAt(...) as there is no back pointer to the defining method (scope is null after resolution has ended)
try {
- return cu.getElementAt(node.getStartPosition());
+ return (JavaElement) cu.getElementAt(node.getStartPosition());
} catch (JavaModelException e) {
// does not exist
return null;
@@ -406,11 +423,11 @@
if (declaringElement instanceof MethodBinding) {
declaringTypeBinding = this.resolver.getMethodBinding((MethodBinding) declaringElement);
IMethod declaringMethod = (IMethod) declaringTypeBinding.getJavaElement();
- return declaringMethod.getTypeParameter(typeVariableName);
+ return (JavaElement) declaringMethod.getTypeParameter(typeVariableName);
} else {
declaringTypeBinding = this.resolver.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaringElement);
IType declaringType = (IType) declaringTypeBinding.getJavaElement();
- return declaringType.getTypeParameter(typeVariableName);
+ return (JavaElement) declaringType.getTypeParameter(typeVariableName);
}
} else {
if (fileName == null) return null; // case of a WilCardBinding that doesn't have a corresponding Java element
@@ -420,12 +437,12 @@
// top level type
ICompilationUnit cu = getCompilationUnit(fileName);
if (cu == null) return null;
- return cu.getType(new String(referenceBinding.sourceName()));
+ return (JavaElement) cu.getType(new String(referenceBinding.sourceName()));
} else {
// member type
IType declaringType = (IType) declaringTypeBinding.getJavaElement();
if (declaringType == null) return null;
- return declaringType.getType(new String(referenceBinding.sourceName()));
+ return (JavaElement) declaringType.getType(new String(referenceBinding.sourceName()));
}
}
}
@@ -769,22 +786,29 @@
public ITypeBinding[] getTypeBounds() {
if (this.binding instanceof TypeVariableBinding) {
TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
- int boundsNumber = 0;
- ReferenceBinding superclass = typeVariableBinding.superclass();
- if (superclass != null) {
- boundsNumber++;
+ ReferenceBinding varSuperclass = typeVariableBinding.superclass();
+ org.eclipse.jdt.internal.compiler.lookup.TypeBinding firstClassOrArrayBound = typeVariableBinding.firstBound;
+ int boundsLength = 0;
+ if (firstClassOrArrayBound != null) {
+ if (firstClassOrArrayBound == varSuperclass) {
+ boundsLength++;
+ } else if (firstClassOrArrayBound.isArrayType()) { // capture of ? extends/super arrayType
+ boundsLength++;
+ } else {
+ firstClassOrArrayBound = null;
+ }
}
ReferenceBinding[] superinterfaces = typeVariableBinding.superInterfaces();
int superinterfacesLength = 0;
if (superinterfaces != null) {
superinterfacesLength = superinterfaces.length;
- boundsNumber += superinterfacesLength;
+ boundsLength += superinterfacesLength;
}
- if (boundsNumber != 0) {
- ITypeBinding[] typeBounds = new ITypeBinding[boundsNumber];
+ if (boundsLength != 0) {
+ ITypeBinding[] typeBounds = new ITypeBinding[boundsLength];
int boundsIndex = 0;
- if (superclass != null) {
- typeBounds[boundsIndex++] = this.resolver.getTypeBinding(superclass);
+ if (firstClassOrArrayBound != null) {
+ typeBounds[boundsIndex++] = this.resolver.getTypeBinding(firstClassOrArrayBound);
}
if (superinterfaces != null) {
for (int i = 0; i < superinterfacesLength; i++, boundsIndex++) {
@@ -894,14 +918,17 @@
};
Scope scope = this.resolver.scope();
if (scope == null) return false;
- return expression.checkCastTypesCompatibility(scope, this.binding, ((TypeBinding) type).binding, null);
+ org.eclipse.jdt.internal.compiler.lookup.TypeBinding expressionType = ((TypeBinding) type).binding;
+ // simulate capture in case checked binding did not properly get extracted from a reference
+ expressionType = expressionType.capture(scope, 0);
+ return expression.checkCastTypesCompatibility(scope, this.binding, expressionType, null);
}
/*
* @see ITypeBinding#isClass()
*/
public boolean isClass() {
- return this.binding.isClass() && !this.binding.isTypeVariable();
+ return this.binding.isClass() && !this.binding.isTypeVariable() && !this.binding.isWildcard();
}
/*
@@ -961,6 +988,28 @@
} else {
return !referenceBinding.isBinaryBinding();
}
+ } else if (isTypeVariable()) {
+ final TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+ final Binding declaringElement = typeVariableBinding.declaringElement;
+ if (declaringElement instanceof MethodBinding) {
+ MethodBinding methodBinding = (MethodBinding) declaringElement;
+ return !methodBinding.declaringClass.isBinaryBinding();
+ } else {
+ final org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = (org.eclipse.jdt.internal.compiler.lookup.TypeBinding) declaringElement;
+ if (typeBinding instanceof ReferenceBinding) {
+ return !((ReferenceBinding) typeBinding).isBinaryBinding();
+ } else if (typeBinding instanceof ArrayBinding) {
+ final ArrayBinding arrayBinding = (ArrayBinding) typeBinding;
+ final org.eclipse.jdt.internal.compiler.lookup.TypeBinding leafComponentType = arrayBinding.leafComponentType;
+ if (leafComponentType instanceof ReferenceBinding) {
+ return !((ReferenceBinding) leafComponentType).isBinaryBinding();
+ }
+ }
+ }
+
+ } else if (isCapture()) {
+ CaptureBinding captureBinding = (CaptureBinding) this.binding;
+ return !captureBinding.sourceType.isBinaryBinding();
}
return false;
}
@@ -969,7 +1018,7 @@
* @see ITypeBinding#isInterface()
*/
public boolean isInterface() {
- return this.binding.isInterface();
+ return this.binding.isInterface() && !this.binding.isTypeVariable() && !this.binding.isWildcard();
}
/*
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
index 17532f0..6e4fa9c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
@@ -125,13 +125,20 @@
* @see IBinding#getJavaElement()
*/
public IJavaElement getJavaElement() {
+ JavaElement element = getUnresolvedJavaElement();
+ if (element == null)
+ return null;
+ return element.resolved(this.binding);
+ }
+
+ private JavaElement getUnresolvedJavaElement() {
if (isField()) {
// field
FieldBinding fieldBinding = (FieldBinding) this.binding;
if (fieldBinding.declaringClass == null) return null; // arraylength
IType declaringType = (IType) getDeclaringClass().getJavaElement();
if (declaringType == null) return null;
- return declaringType.getField(getName());
+ return (JavaElement) declaringType.getField(getName());
}
// local variable
IMethodBinding declaringMethod = getDeclaringMethod();
@@ -153,9 +160,9 @@
} else {
nameStart = localVar.getStartPosition();
nameLength = localVar.getLength();
- VariableDeclarationStatement statement = (VariableDeclarationStatement) localVar.getParent();
- sourceStart = statement.getStartPosition();
- sourceLength = statement.getLength();
+ ASTNode node = localVar.getParent();
+ sourceStart = node.getStartPosition();
+ sourceLength = node.getLength();
}
char[] typeSig = this.binding.type.genericTypeSignature();
return new LocalVariable(method, localVar.getName().getIdentifier(), sourceStart, sourceStart+sourceLength-1, nameStart, nameStart+nameLength-1, new String(typeSig));
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java
index 0c5e848..9cd1c5b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java
@@ -178,10 +178,14 @@
if (rootNode != null) {
//validateASTNotModified(rootNode);
- getRewriteEventStore().markMovedNodesRemoved();
+ TargetSourceRangeComputer sourceRangeComputer= getExtendedSourceRangeComputer();
+
+ this.eventStore.prepareMovedNodes(sourceRangeComputer);
- ASTRewriteAnalyzer visitor= new ASTRewriteAnalyzer(document, result, this.eventStore, this.nodeStore, options, getExtendedSourceRangeComputer());
+ ASTRewriteAnalyzer visitor= new ASTRewriteAnalyzer(document, result, this.eventStore, this.nodeStore, options, sourceRangeComputer);
rootNode.accept(visitor); // throws IllegalArgumentException
+
+ this.eventStore.revertMovedNodes();
}
return result;
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java
index 540603b..9aa2b12 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java
@@ -13,19 +13,18 @@
import java.util.Collections;
import java.util.List;
-import org.eclipse.text.edits.TextEditGroup;
-
import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
-
import org.eclipse.jdt.internal.core.dom.rewrite.ListRewriteEvent;
import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore;
import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEvent;
import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore;
import org.eclipse.jdt.internal.core.dom.rewrite.RewriteEventStore.CopySourceInfo;
+import org.eclipse.text.edits.TextEditGroup;
/**
* For describing manipulations to a child list property of an AST node.
@@ -290,18 +289,19 @@
}
- private ASTNode createTargetNode(ASTNode first, ASTNode last, boolean isMove) {
+ private ASTNode createTargetNode(ASTNode first, ASTNode last, boolean isMove, ASTNode replacingNode, TextEditGroup editGroup) {
if (first == null || last == null) {
throw new IllegalArgumentException();
}
- //validateIsInsideAST(node);
- CopySourceInfo info= getRewriteStore().markAsRangeCopySource(this.parent, this.childProperty, first, last, isMove);
-
+
NodeInfoStore nodeStore= this.rewriter.getNodeStore();
ASTNode placeholder= nodeStore.newPlaceholderNode(first.getNodeType()); // revisit: could use list type
if (placeholder == null) {
throw new IllegalArgumentException("Creating a target node is not supported for nodes of type" + first.getClass().getName()); //$NON-NLS-1$
}
+
+ Block internalPlaceHolder= nodeStore.createCollapsePlaceholder();
+ CopySourceInfo info= getRewriteStore().createRangeCopy(this.parent, this.childProperty, first, last, isMove, internalPlaceHolder, replacingNode, editGroup);
nodeStore.markAsCopyTarget(placeholder, info);
return placeholder;
@@ -318,14 +318,16 @@
* @param first the node that starts the range
* @param last the node that ends the range
* @return the new placeholder node
- * @throws IllegalArgumentException if the node is null, or if the node
- * is not part of this rewriter's AST
+ * @throws IllegalArgumentException An exception is thrown if the first or last node
+ * are <code>null</code>, if a node is not a child of the current list or if the first node
+ * is not before the last node. An <code>IllegalArgumentException</code> is
+ * also thrown if the copied range is overlapping with an other moved or copied range.
*/
public final ASTNode createCopyTarget(ASTNode first, ASTNode last) {
if (first == last) {
return this.rewriter.createCopyTarget(first);
} else {
- return createTargetNode(first, last, false);
+ return createTargetNode(first, last, false, null, null);
}
}
@@ -340,16 +342,47 @@
* @param first the node that starts the range
* @param last the node that ends the range
* @return the new placeholder node
- * @throws IllegalArgumentException if the node is null, or if the node
- * is not part of this rewriter's AST
+ * @throws IllegalArgumentException An exception is thrown if the first or last node
+ * are <code>null</code>, if a node is not a child of the current list or if the first node
+ * is not before the last node. An <code>IllegalArgumentException</code> is
+ * also thrown if the moved range is overlapping with an other moved or copied range.
*
* @since 3.1
*/
public final ASTNode createMoveTarget(ASTNode first, ASTNode last) {
+ return createMoveTarget(first, last, null, null);
+ }
+
+ /**
+ * Creates and returns a placeholder node for a move of a range of nodes of the
+ * current list. The moved nodes can optionally be replaced by a specified node.
+ *
+ * The placeholder node can either be inserted as new or used to replace an
+ * existing node. When the document is rewritten, a copy of the source code
+ * for the given node range is inserted into the output document at the position
+ * corresponding to the placeholder (indentation is adjusted).
+ *
+ * @param first the node that starts the range
+ * @param last the node that ends the range
+ * @param replacingNode a node that is set at the location of the moved nodes
+ * or <code>null</code> to remove all nodes
+ * @param editGroup the edit group in which to collect the corresponding
+ * text edits fro a replace, or <code>null</code> if ungrouped
+ * @return the new placeholder node
+ * @throws IllegalArgumentException An exception is thrown if the first or
+ * last node are <code>null</code>, if a node is not a child of the current list or
+ * if the first node is not before the last node. An <code>IllegalArgumentException
+ * </code> is also thrown if the moved range is overlapping with an other moved
+ * or copied range.
+ *
+ * @since 3.1
+ */
+ public final ASTNode createMoveTarget(ASTNode first, ASTNode last, ASTNode replacingNode, TextEditGroup editGroup) {
if (first == last) {
+ replace(first, replacingNode, editGroup);
return this.rewriter.createMoveTarget(first);
} else {
- return createTargetNode(first, last, true);
+ return createTargetNode(first, last, true, replacingNode, editGroup);
}
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java
index 2c24289..1104552 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java
@@ -125,9 +125,11 @@
* that should be replaced (or deleted)
*/
public SourceRange computeSourceRange(ASTNode node) {
- CompilationUnit cu = (CompilationUnit) node.getRoot();
- return new SourceRange(
- cu.getExtendedStartPosition(node),
- cu.getExtendedLength(node));
+ ASTNode root= node.getRoot();
+ if (root instanceof CompilationUnit) {
+ CompilationUnit cu= (CompilationUnit) root;
+ return new SourceRange(cu.getExtendedStartPosition(node), cu.getExtendedLength(node));
+ }
+ return new SourceRange(node.getStartPosition(), node.getLength());
}
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/package.html b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/package.html
new file mode 100644
index 0000000..2f568ac
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/package.html
@@ -0,0 +1,18 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="IBM">
+ <title>Package-level Javadoc</title>
+</head>
+<body>
+The Java DOM/AST rewrite is the set of classes that are used to make changes to an existing DOM/AST tree.
+
+<h2>
+Package Specification</h2>
+
+<p>This package contains the Java DOM/AST classes used to make changes to an existing DOM/AST tree.
+The principal classes are {@link org.eclipse.jdt.core.dom.rewrite.ASTRewrite ASTRewrite} and
+{@link org.eclipse.jdt.core.dom.rewrite.ListRewrite ListRewrite}.</p>
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
index 81f09de..957af20 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
@@ -114,41 +114,33 @@
}
/**
- * Returns the extended source range computer for this AST rewriter.
+ * Returns the extended source range for a node.
*
- * @return an extended source range computer (never null)
+ * @return an extended source range (never null)
* @since 3.1
*/
- private TargetSourceRangeComputer getExtendedSourceRangeComputer() {
- return this.extendedSourceRangeComputer;
- }
-
final SourceRange getExtendedRange(ASTNode node) {
- return getExtendedSourceRangeComputer().computeSourceRange(node);
+ if (this.eventStore.isRangeCopyPlaceholder(node)) {
+ return new SourceRange(node.getStartPosition(), node.getLength());
+ }
+ return this.extendedSourceRangeComputer.computeSourceRange(node);
}
final int getExtendedOffset(ASTNode node) {
- return getExtendedSourceRangeComputer().computeSourceRange(node).getStartPosition();
+ return getExtendedRange(node).getStartPosition();
}
final int getExtendedEnd(ASTNode node) {
- TargetSourceRangeComputer.SourceRange range =
- getExtendedSourceRangeComputer().computeSourceRange(node);
+ TargetSourceRangeComputer.SourceRange range= getExtendedRange(node);
return range.getStartPosition() + range.getLength();
}
final TextEdit getCopySourceEdit(CopySourceInfo info) {
TextEdit edit= (TextEdit) this.sourceCopyInfoToEdit.get(info);
if (edit == null) {
- int start, end;
- if (info.getStartNode() == info.getEndNode()) {
- SourceRange range= getExtendedRange(info.getStartNode());
- start= range.getStartPosition();
- end= start + range.getLength();
- } else {
- start= getExtendedOffset(info.getStartNode());
- end= getExtendedEnd(info.getEndNode());
- }
+ SourceRange range= getExtendedRange(info.getNode());
+ int start= range.getStartPosition();
+ int end= start + range.getLength();
if (info.isMove) {
MoveSourceEdit moveSourceEdit= new MoveSourceEdit(start, end - start);
moveSourceEdit.setTargetEdit(new MoveTargetEdit(0));
@@ -284,32 +276,18 @@
if (property.isChildProperty() && node != null) {
return doVisit((ASTNode) node);
} else if (property.isChildListProperty()) {
- boolean hasRangeCopySources= this.eventStore.hasRangeCopySources(parent, property);
- return doVisitList((List) node, offset, hasRangeCopySources);
+ return doVisitList((List) node, offset);
}
return offset;
}
- private int doVisitList(List list, int offset, boolean hasRangeCopySources) {
- if (hasRangeCopySources) {
- // list with copy source ranges
- Stack nodeRangeEndStack= new Stack();
- int endPos= offset;
- for (Iterator iter= list.iterator(); iter.hasNext();) {
- ASTNode curr= ((ASTNode) iter.next());
- doCopySourcePreVisit(this.eventStore.getRangeCopySources(curr), nodeRangeEndStack);
- endPos= doVisit(curr);
- doCopySourcePostVisit(curr, nodeRangeEndStack);
- }
- return endPos;
- } else {
- int endPos= offset;
- for (Iterator iter= list.iterator(); iter.hasNext();) {
- ASTNode curr= ((ASTNode) iter.next());
- endPos= doVisit(curr);
- }
- return endPos;
+ private int doVisitList(List list, int offset) {
+ int endPos= offset;
+ for (Iterator iter= list.iterator(); iter.hasNext();) {
+ ASTNode curr= ((ASTNode) iter.next());
+ endPos= doVisit(curr);
}
+ return endPos;
}
final void voidVisit(ASTNode node) {
@@ -321,42 +299,20 @@
if (property.isChildProperty() && node != null) {
voidVisit((ASTNode) node);
} else if (property.isChildListProperty()) {
- boolean hasRangeCopySources= this.eventStore.hasRangeCopySources(parent, property);
- voidVisitList((List) node, hasRangeCopySources);
+ voidVisitList((List) node);
}
}
- private void voidVisitList(List list, boolean hasRangeCopySources) {
- if (hasRangeCopySources) {
- // list with copy source ranges
- Stack nodeRangeEndStack= new Stack();
- for (Iterator iter= list.iterator(); iter.hasNext();) {
- ASTNode curr= ((ASTNode) iter.next());
- doCopySourcePreVisit(this.eventStore.getRangeCopySources(curr), nodeRangeEndStack);
- doVisit(curr);
- doCopySourcePostVisit(curr, nodeRangeEndStack);
- }
- } else {
- for (Iterator iter= list.iterator(); iter.hasNext();) {
- doVisit(((ASTNode) iter.next()));
- }
+ private void voidVisitList(List list) {
+ for (Iterator iter= list.iterator(); iter.hasNext();) {
+ doVisit(((ASTNode) iter.next()));
}
}
private final boolean doVisitUnchangedChildren(ASTNode parent) {
List properties= parent.structuralPropertiesForType();
for (int i= 0; i < properties.size(); i++) {
- StructuralPropertyDescriptor property= (StructuralPropertyDescriptor) properties.get(i);
- if (property.isChildProperty()) {
- ASTNode child= (ASTNode) parent.getStructuralProperty(property);
- if (child != null) {
- voidVisit(child);
- }
- } else if (property.isChildListProperty()) {
- List list= (List) parent.getStructuralProperty(property);
- boolean hasRangeCopySources= this.eventStore.hasRangeCopySources(parent, property);
- voidVisitList(list, hasRangeCopySources);
- }
+ voidVisit(parent, (StructuralPropertyDescriptor) properties.get(i));
}
return false;
}
@@ -409,12 +365,14 @@
protected RewriteEvent[] list;
- private Stack copyRangeEndStack;
-
protected final ASTNode getOriginalNode(int index) {
return (ASTNode) this.list[index].getOriginalValue();
}
+ protected final ASTNode getNewNode(int index) {
+ return (ASTNode) this.list[index].getNewValue();
+ }
+
protected String getSeparatorString(int nodeIndex) {
return this.contantSeparator;
}
@@ -422,7 +380,7 @@
protected int getInitialIndent() {
return getIndent(this.startPos);
}
-
+
protected int getNodeIndent(int nodeIndex) {
ASTNode node= getOriginalNode(nodeIndex);
if (node == null) {
@@ -465,8 +423,6 @@
this.startPos= offset;
this.list= getEvent(parent, property).getChildren();
- initCopyRangeChecks(parent, property);
-
int total= this.list.length;
if (total == 0) {
return this.startPos;
@@ -543,17 +499,13 @@
if (i > lastNonDelete && separatorState == EXISTING) {
// is last, remove previous separator: split delete to allow range copies
doTextRemove(prevEnd, currPos - prevEnd, editGroup); // remove separator
- checkForRangeStart(node);
doTextRemoveAndVisit(currPos, currEnd - currPos, node, editGroup); // remove node
- checkForRangeEnd(node);
currPos= currEnd;
prevEnd= currEnd;
} else {
// remove element and next separator
int end= getStartOfNextNode(nextIndex, currEnd); // start of next
- checkForRangeStart(node);
doTextRemoveAndVisit(currPos, currEnd - currPos, node, getEditGroup(currEvent)); // remove node
- checkForRangeEnd(node);
doTextRemove(currEnd, end - currEnd, editGroup); // remove separator
currPos= end;
prevEnd= currEnd;
@@ -566,17 +518,13 @@
TextEditGroup editGroup= getEditGroup(currEvent);
ASTNode changed= (ASTNode) currEvent.getNewValue();
- checkForRangeStart(node);
doTextRemoveAndVisit(currPos, currEnd - currPos, node, editGroup);
doTextInsert(currPos, changed, getNodeIndent(i), true, editGroup);
- checkForRangeEnd(node);
prevEnd= currEnd;
} else { // is unchanged
ASTNode node= (ASTNode) currEvent.getOriginalValue();
- checkForRangeStart(node);
voidVisit(node);
- checkForRangeEnd(node);
}
if (i == lastNonInsert) { // last node or next nodes are all inserts
separatorState= NONE;
@@ -600,23 +548,6 @@
return currPos;
}
- private void initCopyRangeChecks(ASTNode parent, StructuralPropertyDescriptor property) {
- if (ASTRewriteAnalyzer.this.eventStore.hasRangeCopySources(parent, property)) {
- this.copyRangeEndStack= new Stack();
- }
- }
-
- private void checkForRangeStart(ASTNode node) {
- if (this.copyRangeEndStack != null) {
- doCopySourcePreVisit(ASTRewriteAnalyzer.this.eventStore.getRangeCopySources(node), this.copyRangeEndStack);
- }
- }
-
- private void checkForRangeEnd(ASTNode node) {
- if (this.copyRangeEndStack != null) {
- doCopySourcePostVisit(node, this.copyRangeEndStack);
- }
- }
}
private int rewriteRequiredNode(ASTNode parent, StructuralPropertyDescriptor property) {
@@ -917,7 +848,7 @@
return listRewriter.rewriteList(parent, property, insertPos, leadString.toString());
}
- private int rewriteOptionalTypeParameters(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword, boolean adjustOnNext) {
+ private int rewriteOptionalTypeParameters(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword, boolean adjustOnNext, boolean needsSpaceOnRemoveAll) {
int pos= offset;
RewriteEvent event= getEvent(parent, property);
if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
@@ -929,13 +860,18 @@
}
boolean isAllRemoved= !isAllInserted && isAllOfKind(children, RewriteEvent.REMOVED);
if (isAllRemoved) { // all removed: set start to left bracket
- pos= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNameLESS, pos);
+ int posBeforeOpenBracket= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNameLESS, pos);
+ if (posBeforeOpenBracket != pos) {
+ needsSpaceOnRemoveAll= false;
+ }
+ pos= posBeforeOpenBracket;
}
pos= new ListRewriter().rewriteList(parent, property, pos, String.valueOf('<'), ", "); //$NON-NLS-1$ //$NON-NLS-2$
if (isAllRemoved) { // all removed: remove right and space up to next element
int endPos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameGREATER, pos); // set pos to '>'
endPos= getScanner().getNextStartOffset(endPos, false);
- doTextRemove(pos, endPos - pos, getEditGroup(children[children.length - 1]));
+ String replacement= needsSpaceOnRemoveAll ? String.valueOf(' ') : new String();
+ doTextReplace(pos, endPos - pos, replacement, getEditGroup(children[children.length - 1]));
return endPos;
} else if (isAllInserted) {
doTextInsert(pos, String.valueOf('>' + keyword), getEditGroup(children[children.length - 1]));
@@ -1109,7 +1045,7 @@
String destIndentString= this.formatter.getIndentString(getCurrentLine(formatted, offset));
if (data instanceof CopyPlaceholderData) { // replace with a copy/move target
CopySourceInfo copySource= ((CopyPlaceholderData) data).copySource;
- int srcIndentLevel= getIndent(copySource.getStartNode().getStartPosition());
+ int srcIndentLevel= getIndent(copySource.getNode().getStartPosition());
TextEdit sourceEdit= getCopySourceEdit(copySource);
doTextCopy(sourceEdit, insertOffset, srcIndentLevel, destIndentString, editGroup);
currPos= offset + curr.length; // continue to insert after the replaced string
@@ -1201,6 +1137,27 @@
}
}
+ private class ModifierRewriter extends ListRewriter {
+
+ private final Prefix annotationSeparation;
+
+ public ModifierRewriter(Prefix annotationSeparation) {
+ this.annotationSeparation= annotationSeparation;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer.ListRewriter#getSeparatorString(int)
+ */
+ protected String getSeparatorString(int nodeIndex) {
+ ASTNode curr= getNewNode(nodeIndex);
+ if (curr instanceof Annotation) {
+ return this.annotationSeparation.getPrefix(getNodeIndent(nodeIndex + 1));
+ }
+ return super.getSeparatorString(nodeIndex);
+ }
+ }
+
+
private int rewriteModifiers2(ASTNode node, ChildListPropertyDescriptor property, int pos) {
RewriteEvent event= getEvent(node, property);
if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) {
@@ -1217,7 +1174,8 @@
handleException(e);
}
}
- int endPos= rewriteNodeList(node, property, pos, "", " "); //$NON-NLS-1$ //$NON-NLS-2$
+
+ int endPos= new ModifierRewriter(this.formatter.ANNOTATION_SEPARATION).rewriteList(node, property, pos, "", " "); //$NON-NLS-1$ //$NON-NLS-2$
if (isAllInsert) {
doTextInsert(endPos, " ", getEditGroup(children[children.length - 1])); //$NON-NLS-1$
@@ -1297,7 +1255,7 @@
TextEdit edit= getCopySourceEdit(curr);
addEdit(edit);
this.currentEdit= edit;
- nodeEndStack.push(curr.getEndNode());
+ nodeEndStack.push(curr.getNode());
}
}
}
@@ -1368,7 +1326,7 @@
pos= rewriteRequiredNode(node, TypeDeclaration.NAME_PROPERTY);
if (apiLevel >= AST.JLS3) {
- pos= rewriteOptionalTypeParameters(node, TypeDeclaration.TYPE_PARAMETERS_PROPERTY, pos, "", false); //$NON-NLS-1$
+ pos= rewriteOptionalTypeParameters(node, TypeDeclaration.TYPE_PARAMETERS_PROPERTY, pos, "", false, true); //$NON-NLS-1$
}
// superclass
@@ -1486,7 +1444,7 @@
rewriteModifiers(node, MethodDeclaration.MODIFIERS_PROPERTY, pos);
} else {
pos= rewriteModifiers2(node, MethodDeclaration.MODIFIERS2_PROPERTY, pos);
- pos= rewriteOptionalTypeParameters(node, MethodDeclaration.TYPE_PARAMETERS_PROPERTY, pos, " ", true); //$NON-NLS-1$
+ pos= rewriteOptionalTypeParameters(node, MethodDeclaration.TYPE_PARAMETERS_PROPERTY, pos, " ", true, pos != node.getStartPosition()); //$NON-NLS-1$
}
boolean isConstructorChange= isChanged(node, MethodDeclaration.CONSTRUCTOR_PROPERTY);
@@ -1846,7 +1804,7 @@
if (isChanged(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY)) {
try {
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNamenew, pos); //after 'new'
- rewriteOptionalTypeParameters(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY, pos, " ", true); //$NON-NLS-1$
+ rewriteOptionalTypeParameters(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY, pos, " ", true, true); //$NON-NLS-1$
} catch (CoreException e) {
handleException(e);
}
@@ -1904,7 +1862,7 @@
}
int pos= node.getStartPosition();
if (node.getAST().apiLevel() >= AST.JLS3) {
- pos= rewriteOptionalTypeParameters(node, ConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false); //$NON-NLS-1$
+ pos= rewriteOptionalTypeParameters(node, ConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false, false); //$NON-NLS-1$
}
try {
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos);
@@ -2278,7 +2236,7 @@
int pos= rewriteOptionalQualifier(node, MethodInvocation.EXPRESSION_PROPERTY, node.getStartPosition());
if (node.getAST().apiLevel() >= AST.JLS3) {
- pos= rewriteOptionalTypeParameters(node, MethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false); //$NON-NLS-1$
+ pos= rewriteOptionalTypeParameters(node, MethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false, false); //$NON-NLS-1$
}
pos= rewriteRequiredNode(node, MethodInvocation.NAME_PROPERTY);
@@ -2501,7 +2459,7 @@
int pos= rewriteOptionalQualifier(node, SuperConstructorInvocation.EXPRESSION_PROPERTY, node.getStartPosition());
if (node.getAST().apiLevel() >= AST.JLS3) {
- pos= rewriteOptionalTypeParameters(node, SuperConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false); //$NON-NLS-1$
+ pos= rewriteOptionalTypeParameters(node, SuperConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false, false); //$NON-NLS-1$
}
if (isChanged(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY)) {
@@ -2545,7 +2503,7 @@
if (isChanged(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY)) {
try {
pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameDOT, pos);
- rewriteOptionalTypeParameters(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false); //$NON-NLS-1$
+ rewriteOptionalTypeParameters(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false, false); //$NON-NLS-1$
} catch (CoreException e) {
handleException(e);
}
@@ -2884,52 +2842,45 @@
int changeKind= getChangeKind(node, TagElement.TAG_NAME_PROPERTY);
switch (changeKind) {
case RewriteEvent.INSERTED: {
- String newTagName= '@' + (String) getNewValue(node, TagElement.TAG_NAME_PROPERTY);
+ String newTagName= (String) getNewValue(node, TagElement.TAG_NAME_PROPERTY);
doTextInsert(node.getStartPosition(), newTagName, getEditGroup(node, TagElement.TAG_NAME_PROPERTY));
break;
}
case RewriteEvent.REMOVED: {
- String oldTag= (String) getOriginalValue(node, TagElement.TAG_NAME_PROPERTY);
- int tagEnd= findTagNameStart(node) + oldTag.length();
- doTextRemove(node.getStartPosition(), tagEnd - node.getStartPosition(), getEditGroup(node, TagElement.TAG_NAME_PROPERTY));
+ doTextRemove(node.getStartPosition(), findTagNameEnd(node) - node.getStartPosition(), getEditGroup(node, TagElement.TAG_NAME_PROPERTY));
break;
}
case RewriteEvent.REPLACED: {
String newTagName= (String) getNewValue(node, TagElement.TAG_NAME_PROPERTY);
- String oldTag= (String) getOriginalValue(node, TagElement.TAG_NAME_PROPERTY);
- int tagStart= findTagNameStart(node);
- doTextReplace(tagStart, oldTag.length(), newTagName, getEditGroup(node, TagElement.TAG_NAME_PROPERTY));
+ doTextReplace(node.getStartPosition(), findTagNameEnd(node) - node.getStartPosition(), newTagName, getEditGroup(node, TagElement.TAG_NAME_PROPERTY));
break;
}
}
if (isChanged(node, TagElement.FRAGMENTS_PROPERTY)) {
// eval position after name
- int startOffset= node.getStartPosition();
- String oldTag= (String) getOriginalValue(node, TagElement.TAG_NAME_PROPERTY);
- if (oldTag != null) {
- startOffset= findTagNameStart(node) + oldTag.length();
- }
-
- rewriteNodeList(node, TagElement.FRAGMENTS_PROPERTY, startOffset, " ", " "); //$NON-NLS-1$//$NON-NLS-2$
+ int endOffset= findTagNameEnd(node);
+ rewriteNodeList(node, TagElement.FRAGMENTS_PROPERTY, endOffset, " ", " "); //$NON-NLS-1$//$NON-NLS-2$
} else {
voidVisit(node, TagElement.FRAGMENTS_PROPERTY);
}
return false;
}
- private int findTagNameStart(ASTNode tagNode) {
- try {
- IDocument doc = getDocument();
- int i= tagNode.getStartPosition();
- int end= i + tagNode.getLength();
- while (i < end && !Character.isJavaIdentifierStart(doc.getChar(i))) {
- i++;
- }
- return i;
- } catch (BadLocationException e) {
- handleException(e);
- }
+ private int findTagNameEnd(TagElement tagNode) {
+ if (tagNode.getTagName() != null) {
+ try {
+ IDocument doc = getDocument();
+ int len= doc.getLength();
+ int i= tagNode.getStartPosition();
+ while (i < len && !Indents.isIndentChar(doc.getChar(i))) {
+ i++;
+ }
+ return i;
+ } catch (BadLocationException e) {
+ handleException(e);
+ }
+ }
return tagNode.getStartPosition();
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
index c0a105f..ffb0621 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
@@ -334,8 +334,8 @@
code= CodeFormatter.K_COMPILATION_UNIT;
break;
case ASTNode.JAVADOC:
- suffix= "void foo();"; //$NON-NLS-1$
- code= CodeFormatter.K_CLASS_BODY_DECLARATIONS;
+ suffix= "\nclass A {}"; //$NON-NLS-1$
+ code= CodeFormatter.K_COMPILATION_UNIT;
break;
case ASTNode.CATCH_CLAUSE:
prefix= "try {}"; //$NON-NLS-1$
@@ -365,8 +365,27 @@
case ASTNode.METHOD_REF_PARAMETER:
case ASTNode.TAG_ELEMENT:
case ASTNode.TEXT_ELEMENT:
- // Javadoc formatting not yet supported:
- return null;
+ // javadoc formatting disabled due to bug 93644
+ return null;
+
+// wiat for bug 93644
+// case ASTNode.MEMBER_REF:
+// case ASTNode.METHOD_REF:
+// prefix= "/**\n * @see "; //$NON-NLS-1$
+// suffix= "\n*/"; //$NON-NLS-1$
+// code= CodeFormatter.K_JAVA_DOC;
+// break;
+// case ASTNode.METHOD_REF_PARAMETER:
+// prefix= "/**\n * @see A#foo("; //$NON-NLS-1$
+// suffix= ")\n*/"; //$NON-NLS-1$
+// code= CodeFormatter.K_JAVA_DOC;
+// break;
+// case ASTNode.TAG_ELEMENT:
+// case ASTNode.TEXT_ELEMENT:
+// prefix= "/**\n * "; //$NON-NLS-1$
+// suffix= "\n*/"; //$NON-NLS-1$
+// code= CodeFormatter.K_JAVA_DOC;
+// break;
default:
//Assert.isTrue(false, "Node type not covered: " + node.getClass().getName()); //$NON-NLS-1$
return null;
@@ -375,6 +394,7 @@
String concatStr= prefix + str + suffix;
TextEdit edit= ToolFactory.createCodeFormatter(options).format(code, concatStr, prefix.length(), str.length(), indentationLevel, lineSeparator);
+
if (prefix.length() > 0) {
edit= shifEdit(edit, prefix.length());
}
@@ -554,7 +574,8 @@
public final Prefix WILDCARD_SUPER= new FormattingPrefix("A<? super B> a;", "? super B" , CodeFormatter.K_CLASS_BODY_DECLARATIONS); //$NON-NLS-1$ //$NON-NLS-2$
public final Prefix FIRST_ENUM_CONST= new FormattingPrefix("enum E { X;}", "{ X" , CodeFormatter.K_COMPILATION_UNIT); //$NON-NLS-1$ //$NON-NLS-2$
-
+ public final Prefix ANNOTATION_SEPARATION= new FormattingPrefix("@A @B class C {}", "A @" , CodeFormatter.K_COMPILATION_UNIT); //$NON-NLS-1$ //$NON-NLS-2$
+
public final BlockContext IF_BLOCK_WITH_ELSE= new BlockFormattingPrefixSuffix("if (true)", "else{}", 8); //$NON-NLS-1$ //$NON-NLS-2$
public final BlockContext IF_BLOCK_NO_ELSE= new BlockFormattingPrefix("if (true)", 8); //$NON-NLS-1$ //$NON-NLS-2$
public final BlockContext ELSE_AFTER_STATEMENT= new BlockFormattingPrefix("if (true) foo(); else ", 15); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java
index 1445334..c6dda3e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java
@@ -10,23 +10,12 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core.dom.rewrite;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.text.edits.TextEditGroup;
+import java.util.*;
import org.eclipse.jdt.core.Signature;
-
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.*;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
+import org.eclipse.text.edits.TextEditGroup;
/**
@@ -37,8 +26,8 @@
public final class PropertyLocation {
- private ASTNode parent;
- private StructuralPropertyDescriptor property;
+ private final ASTNode parent;
+ private final StructuralPropertyDescriptor property;
public PropertyLocation(ASTNode parent, StructuralPropertyDescriptor property) {
this.parent= parent;
@@ -52,6 +41,19 @@
public StructuralPropertyDescriptor getProperty() {
return this.property;
}
+
+ public boolean equals(Object obj) {
+ if (obj != null && obj.getClass().equals(this.getClass())) {
+ PropertyLocation other= (PropertyLocation) obj;
+ return other.getParent().equals(getParent()) && other.getProperty().equals(getProperty());
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return getParent().hashCode() + getProperty().hashCode();
+ }
+
}
/**
@@ -92,19 +94,60 @@
}
}
- public static class CopySourceInfo {
- public final ASTNode parent;
- public final StructuralPropertyDescriptor childProperty;
- private final ASTNode first;
- private final ASTNode last;
+ public static class CopySourceInfo implements Comparable {
+ public final PropertyLocation location; // can be null, only used to mark as removed on move
+ private final ASTNode node;
public final boolean isMove;
- public CopySourceInfo(ASTNode parent, StructuralPropertyDescriptor childProperty, ASTNode first, ASTNode last, boolean isMove) {
- this.parent= parent;
- this.childProperty= childProperty;
+ public CopySourceInfo(PropertyLocation location, ASTNode node, boolean isMove) {
+ this.location= location;
+ this.node= node;
+ this.isMove= isMove;
+ }
+
+ public ASTNode getNode() {
+ return this.node;
+ }
+
+ public int compareTo(Object o2) {
+ CopySourceInfo r2= (CopySourceInfo) o2;
+
+ int startDiff= this.getNode().getStartPosition() - r2.getNode().getStartPosition();
+ if (startDiff != 0) {
+ return startDiff; // insert before if start node is first
+ }
+
+ if (r2.isMove != this.isMove) {
+ return this.isMove ? -1 : 1; // first move then copy
+ }
+ return 0;
+ }
+
+ public String toString() {
+ StringBuffer buf= new StringBuffer();
+ if (this.isMove) {
+ buf.append("move source: "); //$NON-NLS-1$
+ } else {
+ buf.append("copy source: "); //$NON-NLS-1$
+ }
+ buf.append(this.node);
+ return buf.toString();
+ }
+ }
+
+ private static class NodeRangeInfo implements Comparable {
+ private final ASTNode first;
+ private final ASTNode last;
+ public final CopySourceInfo copyInfo; // containing the internal placeholder and the 'isMove' flag
+ public final ASTNode replacingNode;
+ public final TextEditGroup editGroup;
+
+ public NodeRangeInfo(ASTNode parent, StructuralPropertyDescriptor childProperty, ASTNode first, ASTNode last, CopySourceInfo copyInfo, ASTNode replacingNode, TextEditGroup editGroup) {
this.first= first;
this.last= last;
- this.isMove= isMove;
+ this.copyInfo= copyInfo;
+ this.replacingNode= replacingNode;
+ this.editGroup= editGroup;
}
public ASTNode getStartNode() {
@@ -114,39 +157,59 @@
public ASTNode getEndNode() {
return this.last;
}
-
+
+ public boolean isMove() {
+ return this.copyInfo.isMove;
+ }
+
+ public Block getInternalPlaceholder() {
+ return (Block) this.copyInfo.getNode();
+ }
+
+ public int compareTo(Object o2) {
+ NodeRangeInfo r2= (NodeRangeInfo) o2;
+
+ int startDiff= this.getStartNode().getStartPosition() - r2.getStartNode().getStartPosition();
+ if (startDiff != 0) {
+ return startDiff; // insert before if start node is first
+ }
+ int endDiff= this.getEndNode().getStartPosition() - r2.getEndNode().getStartPosition();
+ if (endDiff != 0) {
+ return -endDiff; // insert before if length is longer
+ }
+ if (r2.isMove() != this.isMove()) {
+ return this.isMove() ? -1 : 1; // first move then copy
+ }
+ return 0;
+ }
+
+ public void updatePlaceholderSourceRanges(TargetSourceRangeComputer sourceRangeComputer) {
+ TargetSourceRangeComputer.SourceRange startRange= sourceRangeComputer.computeSourceRange(getStartNode());
+ TargetSourceRangeComputer.SourceRange endRange= sourceRangeComputer.computeSourceRange(getEndNode());
+ int startPos= startRange.getStartPosition();
+ int endPos= endRange.getStartPosition() + endRange.getLength();
+
+ Block internalPlaceholder= getInternalPlaceholder();
+ internalPlaceholder.setSourceRange(startPos, endPos - startPos);
+ }
+
public String toString() {
StringBuffer buf= new StringBuffer();
if (this.first != this.last) {
buf.append("range "); //$NON-NLS-1$
}
- if (this.isMove) {
+ if (isMove()) {
buf.append("move source: "); //$NON-NLS-1$
} else {
buf.append("copy source: "); //$NON-NLS-1$
}
buf.append(this.first);
- if (this.first != this.last) {
- buf.append(" - "); //$NON-NLS-1$
- buf.append(this.last);
- }
+ buf.append(" - "); //$NON-NLS-1$
+ buf.append(this.last);
return buf.toString();
}
- }
- public static class CopySourceInfoSorter implements Comparator {
- public int compare(Object o1, Object o2) {
- CopySourceInfo e1= (CopySourceInfo) o1;
- CopySourceInfo e2= (CopySourceInfo) o2;
- if (e1.isMove) {
- return -1;
- } else if (e2.isMove) {
- return 1;
- }
- return e2.getEndNode().getStartPosition() - e1.getEndNode().getStartPosition();
- }
-
}
/**
@@ -166,8 +229,8 @@
} else {
this.sourceNodeIter= Collections.EMPTY_LIST.iterator();
}
- if (RewriteEventStore.this.rangeCopySources != null) {
- this.rangeNodeIter= RewriteEventStore.this.rangeCopySources.iterator();
+ if (RewriteEventStore.this.nodeRangeInfos != null) {
+ this.rangeNodeIter= RewriteEventStore.this.nodeRangeInfos.keySet().iterator();
} else {
this.rangeNodeIter= Collections.EMPTY_LIST.iterator();
}
@@ -193,10 +256,10 @@
return ((EventHolder) this.eventIter.next()).parent;
}
if (this.sourceNodeIter.hasNext()) {
- return ((CopySourceInfo) this.sourceNodeIter.next()).getStartNode();
+ return ((CopySourceInfo) this.sourceNodeIter.next()).getNode();
}
if (this.rangeNodeIter.hasNext()) {
- return ((CopySourceInfo) this.rangeNodeIter.next()).parent;
+ return ((PropertyLocation) this.rangeNodeIter.next()).getParent();
}
return this.trackedNodeIter.next();
}
@@ -223,11 +286,11 @@
/** Maps events to group descriptions */
private Map editGroups;
- /** Stores which nodes are source of a copy or move (list of CopyRangeSourceInfo)*/
+ /** Stores which nodes are source of a copy or move (list of CopySourceInfo)*/
List nodeCopySources;
- /** Stores which node ranges that are source of a copy or move (list of CopyRangeSourceInfo)*/
- List rangeCopySources;
+ /** Stores node ranges that are used to copy or move (map of <PropertyLocation, CopyRangeInfo>)*/
+ Map nodeRangeInfos;
/** Stores which nodes are tracked and the corresponding edit group*/
Map trackedNodes;
@@ -238,6 +301,8 @@
/** optional mapper to allow fix already modified AST trees */
private INodePropertyMapper nodePropertyMapper;
+
+ private static final String INTERNAL_PLACEHOLDER_PROPERTY= "rewrite_internal_placeholder"; //$NON-NLS-1$
public RewriteEventStore() {
this.events= new ArrayList();
@@ -250,6 +315,7 @@
this.nodePropertyMapper= null;
this.nodeCopySources= null;
+ this.nodeRangeInfos= null;
}
/**
@@ -485,8 +551,8 @@
setTrackedNodeData(node, editGroup);
}
- public final CopySourceInfo markAsCopySource(ASTNode parent, StructuralPropertyDescriptor property, ASTNode node, boolean isMove) {
- CopySourceInfo copySource= new CopySourceInfo(parent, property, node, node, isMove);
+ private final CopySourceInfo createCopySourceInfo(PropertyLocation location, ASTNode node, boolean isMove) {
+ CopySourceInfo copySource= new CopySourceInfo(location, node, isMove);
if (this.nodeCopySources == null) {
this.nodeCopySources= new ArrayList();
@@ -495,69 +561,19 @@
return copySource;
}
- public final CopySourceInfo markAsRangeCopySource(ASTNode parent, StructuralPropertyDescriptor property, ASTNode first, ASTNode last, boolean isMove) {
- CopySourceInfo copySource= new CopySourceInfo(parent, property, first, last, isMove);
- assertNoOverlap(copySource);
+ public final CopySourceInfo markAsCopySource(ASTNode parent, StructuralPropertyDescriptor property, ASTNode node, boolean isMove) {
+ return createCopySourceInfo(new PropertyLocation(parent, property), node, isMove);
+ }
+
+ public final boolean isRangeCopyPlaceholder(ASTNode node) {
+ return node.getProperty(INTERNAL_PLACEHOLDER_PROPERTY) != null;
+ }
+
+ public final CopySourceInfo createRangeCopy(ASTNode parent, StructuralPropertyDescriptor childProperty, ASTNode first, ASTNode last, boolean isMove, ASTNode internalPlaceholder, ASTNode replacingNode, TextEditGroup editGroup) {
+ CopySourceInfo copyInfo= createCopySourceInfo(null, internalPlaceholder, isMove);
+ internalPlaceholder.setProperty(INTERNAL_PLACEHOLDER_PROPERTY, internalPlaceholder);
- if (this.rangeCopySources == null) {
- this.rangeCopySources= new ArrayList();
- }
- this.rangeCopySources.add(copySource);
- return copySource;
- }
-
-
- public CopySourceInfo[] getNodeCopySources(ASTNode node) {
- if (this.nodeCopySources == null) {
- return null;
- }
- return internalGetCopySources(this.nodeCopySources, node);
- }
-
- public CopySourceInfo[] getRangeCopySources(ASTNode node) {
- if (this.rangeCopySources == null) {
- return null;
- }
- return internalGetCopySources(this.rangeCopySources, node);
- }
-
- public boolean hasRangeCopySources(ASTNode parent, StructuralPropertyDescriptor property) {
- if (this.rangeCopySources == null) {
- return false;
- }
- for (int i= 0; i < this.rangeCopySources.size(); i++) {
- CopySourceInfo curr= (CopySourceInfo) this.rangeCopySources.get(i);
- if (curr.parent == parent && curr.childProperty == property) {
- return true;
- }
- }
- return false;
- }
-
- public CopySourceInfo[] internalGetCopySources(List copySources, ASTNode node) {
- ArrayList res= new ArrayList(3);
- for (int i= 0; i < copySources.size(); i++) {
- CopySourceInfo curr= (CopySourceInfo) copySources.get(i);
- if (curr.getStartNode() == node) {
- res.add(curr);
- }
- }
- if (res.isEmpty()) {
- return null;
- }
- CopySourceInfo[] arr= (CopySourceInfo[]) res.toArray(new CopySourceInfo[res.size()]);
- if (arr.length > 1) {
- Arrays.sort(arr, new CopySourceInfoSorter());
- }
- return arr;
- }
-
-
- private void assertNoOverlap(CopySourceInfo copySource) {
- ASTNode parent= copySource.parent;
- StructuralPropertyDescriptor childProperty= copySource.childProperty;
- ASTNode first= copySource.getStartNode();
- ASTNode last= copySource.getEndNode();
+ NodeRangeInfo copyRangeInfo= new NodeRangeInfo(parent, childProperty, first, last, copyInfo, replacingNode, editGroup);
ListRewriteEvent listEvent= getListEvent(parent, childProperty, true);
@@ -573,46 +589,197 @@
if (indexFirst > indexLast) {
throw new IllegalArgumentException("Start node must be before end node"); //$NON-NLS-1$
}
- if (this.rangeCopySources != null) {
- for (Iterator iter= this.rangeCopySources.iterator(); iter.hasNext();) {
- CopySourceInfo info= (CopySourceInfo) iter.next();
- if (info.parent == parent && info.childProperty == childProperty) {
- int currStart= listEvent.getIndex(first, ListRewriteEvent.BOTH);
- int currEnd= listEvent.getIndex(first, ListRewriteEvent.BOTH);
- if (currStart < indexFirst && currEnd < indexLast && currEnd >= indexFirst
- || currStart > indexFirst && currStart <= currEnd && currEnd > indexLast) {
- throw new IllegalArgumentException("Range overlapps with an existing copy or move range"); //$NON-NLS-1$
- }
- }
+
+ if (this.nodeRangeInfos == null) {
+ this.nodeRangeInfos= new HashMap();
+ }
+ PropertyLocation loc= new PropertyLocation(parent, childProperty);
+ List innerList= (List) this.nodeRangeInfos.get(loc);
+ if (innerList == null) {
+ innerList= new ArrayList(2);
+ this.nodeRangeInfos.put(loc, innerList);
+ } else {
+ assertNoOverlap(listEvent, indexFirst, indexLast, innerList);
+ }
+ innerList.add(copyRangeInfo);
+
+
+ return copyInfo;
+ }
+
+ public CopySourceInfo[] getNodeCopySources(ASTNode node) {
+ if (this.nodeCopySources == null) {
+ return null;
+ }
+ return internalGetCopySources(this.nodeCopySources, node);
+ }
+
+
+ public CopySourceInfo[] internalGetCopySources(List copySources, ASTNode node) {
+ ArrayList res= new ArrayList(3);
+ for (int i= 0; i < copySources.size(); i++) {
+ CopySourceInfo curr= (CopySourceInfo) copySources.get(i);
+ if (curr.getNode() == node) {
+ res.add(curr);
+ }
+ }
+ if (res.isEmpty()) {
+ return null;
+ }
+
+ CopySourceInfo[] arr= (CopySourceInfo[]) res.toArray(new CopySourceInfo[res.size()]);
+ Arrays.sort(arr);
+ return arr;
+ }
+
+
+ private void assertNoOverlap(ListRewriteEvent listEvent, int indexFirst, int indexLast, List innerList) {
+ for (Iterator iter= innerList.iterator(); iter.hasNext();) {
+ NodeRangeInfo curr= (NodeRangeInfo) iter.next();
+ int currStart= listEvent.getIndex(curr.getStartNode(), ListRewriteEvent.BOTH);
+ int currEnd= listEvent.getIndex(curr.getEndNode(), ListRewriteEvent.BOTH);
+ if (currStart < indexFirst && currEnd < indexLast && currEnd >= indexFirst
+ || currStart > indexFirst && currStart <= currEnd && currEnd > indexLast) {
+ throw new IllegalArgumentException("Range overlapps with an existing copy or move range"); //$NON-NLS-1$
}
}
}
+ public void prepareMovedNodes(TargetSourceRangeComputer sourceRangeComputer) {
+ if (this.nodeCopySources != null) {
+ prepareSingleNodeCopies();
+ }
+
+ if (this.nodeRangeInfos != null) {
+ prepareNodeRangeCopies(sourceRangeComputer);
+ }
+ }
+
+ public void revertMovedNodes() {
+ if (this.nodeRangeInfos != null) {
+ removeMoveRangePlaceholders();
+ }
+ }
+
+ private void removeMoveRangePlaceholders() {
+ for (Iterator iter= this.nodeRangeInfos.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry entry= (Map.Entry) iter.next();
+ Set placeholders= new HashSet(); // collect all placeholders
+ List rangeInfos= (List) entry.getValue(); // list of CopySourceRange
+ for (int i= 0; i < rangeInfos.size(); i++) {
+ placeholders.add(((NodeRangeInfo) rangeInfos.get(i)).getInternalPlaceholder());
+ }
+
+ PropertyLocation loc= (PropertyLocation) entry.getKey();
+
+ RewriteEvent[] children= getListEvent(loc.getParent(), loc.getProperty(), true).getChildren();
+ List revertedChildren= new ArrayList();
+ revertListWithRanges(children, placeholders, revertedChildren);
+ RewriteEvent[] revertedChildrenArr= (RewriteEvent[]) revertedChildren.toArray(new RewriteEvent[revertedChildren.size()]);
+ addEvent(loc.getParent(), loc.getProperty(), new ListRewriteEvent(revertedChildrenArr)); // replace the current edits
+ }
+ }
+
+ private void revertListWithRanges(RewriteEvent[] childEvents, Set placeholders, List revertedChildren) {
+ for (int i= 0; i < childEvents.length; i++) {
+ RewriteEvent event= childEvents[i];
+ ASTNode node= (ASTNode) event.getOriginalValue();
+ if (placeholders.contains(node)) {
+ RewriteEvent[] placeholderChildren= getListEvent(node, Block.STATEMENTS_PROPERTY, false).getChildren();
+ revertListWithRanges(placeholderChildren, placeholders, revertedChildren);
+ } else {
+ revertedChildren.add(event);
+ }
+ }
+ }
+
+ private void prepareNodeRangeCopies(TargetSourceRangeComputer sourceRangeComputer) {
+ for (Iterator iter= this.nodeRangeInfos.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry entry= (Map.Entry) iter.next();
+ List rangeInfos= (List) entry.getValue(); // list of CopySourceRange
+ Collections.sort(rangeInfos); // sort by start index, length, move or copy
+
+ PropertyLocation loc= (PropertyLocation) entry.getKey();
+ RewriteEvent[] children= getListEvent(loc.getParent(), loc.getProperty(), true).getChildren();
+
+ RewriteEvent[] newChildren= processListWithRanges(rangeInfos, children, sourceRangeComputer);
+ addEvent(loc.getParent(), loc.getProperty(), new ListRewriteEvent(newChildren)); // replace the current edits
+ }
+ }
+
+ private RewriteEvent[] processListWithRanges(List rangeInfos, RewriteEvent[] childEvents, TargetSourceRangeComputer sourceRangeComputer) {
+ List newChildEvents= new ArrayList(childEvents.length);
+ NodeRangeInfo topInfo= null;
+ Stack newChildrenStack= new Stack();
+ Stack topInfoStack= new Stack();
+
+ Iterator rangeInfoIterator= rangeInfos.iterator();
+ NodeRangeInfo nextInfo= (NodeRangeInfo) rangeInfoIterator.next();
+
+ for (int k= 0; k < childEvents.length; k++) {
+ RewriteEvent event= childEvents[k];
+ ASTNode node= (ASTNode) event.getOriginalValue();
+ // check for ranges and add a placeholder for them
+ while (nextInfo != null && node == nextInfo.getStartNode()) { // is this child the beginning of a range?
+ nextInfo.updatePlaceholderSourceRanges(sourceRangeComputer);
+
+ Block internalPlaceholder= nextInfo.getInternalPlaceholder();
+ RewriteEvent newEvent;
+ if (nextInfo.isMove()) {
+ newEvent= new NodeRewriteEvent(internalPlaceholder, nextInfo.replacingNode); // remove or replace
+ } else {
+ newEvent= new NodeRewriteEvent(internalPlaceholder, internalPlaceholder); // unchanged
+ }
+ newChildEvents.add(newEvent);
+ if (nextInfo.editGroup != null) {
+ setEventEditGroup(newEvent, nextInfo.editGroup);
+ }
+
+ newChildrenStack.push(newChildEvents);
+ topInfoStack.push(topInfo);
+
+ newChildEvents= new ArrayList(childEvents.length);
+ topInfo= nextInfo;
+
+ nextInfo= rangeInfoIterator.hasNext() ? (NodeRangeInfo) rangeInfoIterator.next() : null;
+ }
+
+ newChildEvents.add(event);
+
+ while (topInfo != null && node == topInfo.getEndNode()) {
+ RewriteEvent[] placeholderChildEvents= (RewriteEvent[]) newChildEvents.toArray(new RewriteEvent[newChildEvents.size()]);
+ Block internalPlaceholder= topInfo.getInternalPlaceholder();
+ addEvent(internalPlaceholder, Block.STATEMENTS_PROPERTY, new ListRewriteEvent(placeholderChildEvents));
+
+ newChildEvents= (List) newChildrenStack.pop();
+ topInfo= (NodeRangeInfo) topInfoStack.pop();
+ }
+ }
+ return (RewriteEvent[]) newChildEvents.toArray(new RewriteEvent[newChildEvents.size()]);
+ }
+
/**
* Make sure all moved nodes are marked as removed or replaced.
*/
- public void markMovedNodesRemoved() {
- if (this.nodeCopySources == null) {
- return;
- }
+ private void prepareSingleNodeCopies() {
for (int i= 0; i < this.nodeCopySources.size(); i++) {
CopySourceInfo curr= (CopySourceInfo) this.nodeCopySources.get(i);
- if (curr.isMove) {
- doMarkMovedAsRemoved(curr);
+ if (curr.isMove && curr.location != null) {
+ doMarkMovedAsRemoved(curr, curr.location.getParent(), curr.location.getProperty());
}
}
}
- private void doMarkMovedAsRemoved(CopySourceInfo curr) {
- if (curr.childProperty.isChildListProperty()) {
- ListRewriteEvent event= getListEvent(curr.parent, curr.childProperty, true);
- int index= event.getIndex(curr.getStartNode(), ListRewriteEvent.OLD);
+ private void doMarkMovedAsRemoved(CopySourceInfo curr, ASTNode parent, StructuralPropertyDescriptor childProperty) {
+ if (childProperty.isChildListProperty()) {
+ ListRewriteEvent event= getListEvent(parent, childProperty, true);
+ int index= event.getIndex(curr.getNode(), ListRewriteEvent.OLD);
if (index != -1 && event.getChangeKind(index) == RewriteEvent.UNCHANGED) {
event.setNewValue(null, index);
}
} else {
- NodeRewriteEvent event= getNodeEvent(curr.parent, curr.childProperty, true);
+ NodeRewriteEvent event= getNodeEvent(parent, childProperty, true);
if (event.getChangeKind() == RewriteEvent.UNCHANGED) {
event.setNewValue(null);
}
@@ -665,4 +832,6 @@
public static boolean isNewNode(ASTNode node) {
return (node.getFlags() & ASTNode.ORIGINAL) == 0;
}
+
+
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java
index 253b478..ffa702c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java
@@ -15,6 +15,7 @@
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition;
+import org.eclipse.jface.text.IRegion;
/**
*
@@ -36,7 +37,11 @@
if (this.group.isEmpty()) {
return this.node.getStartPosition();
}
- return TextEdit.getCoverage(this.group.getTextEdits()).getOffset();
+ IRegion coverage= TextEdit.getCoverage(this.group.getTextEdits());
+ if (coverage == null) {
+ return this.node.getStartPosition();
+ }
+ return coverage.getOffset();
}
/* (non-Javadoc)
@@ -46,6 +51,10 @@
if (this.group.isEmpty()) {
return this.node.getLength();
}
- return TextEdit.getCoverage(this.group.getTextEdits()).getLength();
+ IRegion coverage= TextEdit.getCoverage(this.group.getTextEdits());
+ if (coverage == null) {
+ return this.node.getLength();
+ }
+ return coverage.getLength();
}
}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java
index 501ecec..c1939b8 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java
@@ -49,7 +49,7 @@
this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 8);
this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 0);
- this.targetJDK = this.referenceBinding.scope.environment().options.targetJDK;
+ this.targetJDK = this.referenceBinding.scope.compilerOptions().targetJDK;
this.header[this.headerOffset++] = (byte) (targetJDK >> 8); // minor high
this.header[this.headerOffset++] = (byte) (targetJDK >> 0); // minor low
this.header[this.headerOffset++] = (byte) (targetJDK >> 24); // major high
@@ -108,7 +108,7 @@
this.contents[this.contentsOffset++] = (byte) interfaceIndex;
}
}
- this.produceDebugAttributes = this.referenceBinding.scope.environment().options.produceDebugAttributes;
+ this.produceDebugAttributes = this.referenceBinding.scope.compilerOptions().produceDebugAttributes;
this.innerClassesBindings = new ReferenceBinding[INNER_CLASSES_SIZE];
this.creatingProblemType = creatingProblemType;
this.codeStream = new CodeSnippetCodeStream(this);
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java
index d68a9ee..854d920 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java
@@ -126,6 +126,7 @@
this.context,
getMapper().startPosOffset,
getMapper().startPosOffset + this.codeSnippet.length - 1);
+ ((CodeSnippetParser) compiler.parser).lineSeparatorLength = this.context.lineSeparator.length();
// Initialize the compiler's lookup environment with the already compiled super classes
IBinaryType binary = this.context.getRootCodeSnippetBinary();
if (binary != null) {
@@ -180,7 +181,8 @@
this.context.localVariableNames,
this.context.localVariableTypeNames,
this.context.localVariableModifiers,
- this.context.declaringTypeName
+ this.context.declaringTypeName,
+ this.context.lineSeparator
);
}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
index f93863a..336b15c 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
@@ -232,7 +232,7 @@
}
codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
codeStream.sendOperator(postIncrement.operator, this.codegenBinding.type.id);
- codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+ codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
fieldStore(codeStream, this.codegenBinding, null, false);
} else {
this.receiver.generateCode(currentScope, codeStream, !(isStatic = this.codegenBinding.isStatic()));
@@ -280,7 +280,7 @@
codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
codeStream.sendOperator(postIncrement.operator, this.codegenBinding.type.id);
- codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+ codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
((CodeSnippetCodeStream) codeStream).generateEmulatedWriteAccessForField(this.codegenBinding);
}
}
@@ -315,7 +315,7 @@
&& this.binding.declaringClass != null // array.length
&& !this.binding.isConstantValue()) {
- CompilerOptions options = currentScope.environment().options;
+ CompilerOptions options = currentScope.compilerOptions();
if ((options.targetJDK >= ClassFileConstants.JDK1_2
&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !receiver.isImplicitThis() || !this.codegenBinding.isStatic())
&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object fields
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
index 82214f8..767b2bf 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
@@ -10,6 +10,9 @@
*******************************************************************************/
package org.eclipse.jdt.internal.eval;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.CastExpression;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.NameReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
@@ -68,11 +71,7 @@
this.receiver.generateCode(currentScope, codeStream, !isStatic);
}
// generate arguments
- if (this.arguments != null) {
- for (int i = 0, max = this.arguments.length; i < max; i++) {
- this.arguments[i].generateCode(currentScope, codeStream, true);
- }
- }
+ generateArguments(binding, arguments, currentScope, codeStream);
// actual message invocation
if (isStatic) {
codeStream.invokestatic(this.codegenBinding);
@@ -140,24 +139,25 @@
}
}
// operation on the returned value
- if (valueRequired) {
+ if (valueRequired){
// implicit conversion if necessary
- codeStream.generateImplicitConversion(this.implicitConversion);
+ if (this.valueCast != null)
+ codeStream.checkcast(this.valueCast);
+ codeStream.generateImplicitConversion(implicitConversion);
} else {
// pop return value if any
- switch (this.codegenBinding.returnType.id) {
+ switch(binding.returnType.id){
case T_long :
case T_double :
codeStream.pop2();
break;
case T_void :
break;
- default :
+ default:
codeStream.pop();
}
}
- // TODO (philippe) need to revise codegen to include genericCast
- codeStream.recordPositionsFrom(pc, this.sourceStart);
+ codeStream.recordPositionsFrom(pc, (int)(this.nameSourcePosition >>> 32)); // highlight selector
}
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
@@ -181,7 +181,7 @@
// and not from Object or implicit static method call.
if (this.binding.declaringClass != this.actualReceiverType
&& !this.actualReceiverType.isArrayType()) {
- CompilerOptions options = currentScope.environment().options;
+ CompilerOptions options = currentScope.compilerOptions();
if ((options.targetJDK >= ClassFileConstants.JDK1_2
&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !receiver.isImplicitThis() || !this.codegenBinding.isStatic())
&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object methods
@@ -199,22 +199,58 @@
// Base type promotion
this.constant = NotAConstant;
- this.actualReceiverType = this.receiver.resolveType(scope);
+ boolean receiverCast = false, argsContainCast = false;
+ if (this.receiver instanceof CastExpression) {
+ this.receiver.bits |= IgnoreNeedForCastCheckMASK; // will check later on
+ receiverCast = true;
+ }
+ this.actualReceiverType = receiver.resolveType(scope);
+ if (receiverCast && this.actualReceiverType != null) {
+ // due to change of declaring class with receiver type, only identity cast should be notified
+ if (((CastExpression)this.receiver).expression.resolvedType == this.actualReceiverType) {
+ scope.problemReporter().unnecessaryCast((CastExpression)this.receiver);
+ }
+ }
+ // resolve type arguments (for generic constructor call)
+ if (this.typeArguments != null) {
+ int length = this.typeArguments.length;
+ boolean argHasError = false; // typeChecks all arguments
+ this.genericTypeArguments = new TypeBinding[length];
+ for (int i = 0; i < length; i++) {
+ if ((this.genericTypeArguments[i] = this.typeArguments[i].resolveType(scope, true /* check bounds*/)) == null) {
+ argHasError = true;
+ }
+ }
+ if (argHasError) {
+ return null;
+ }
+ }
// will check for null after args are resolved
TypeBinding[] argumentTypes = NoParameters;
if (this.arguments != null) {
boolean argHasError = false; // typeChecks all arguments
int length = this.arguments.length;
argumentTypes = new TypeBinding[length];
- for (int i = 0; i < length; i++)
+ for (int i = 0; i < length; i++) {
+ Expression argument = arguments[i];
+ if (argument instanceof CastExpression) {
+ argument.bits |= IgnoreNeedForCastCheckMASK; // will check later on
+ argsContainCast = true;
+ }
if ((argumentTypes[i] = this.arguments[i].resolveType(scope)) == null)
argHasError = true;
- if (argHasError)
+ }
+ if (argHasError) {
+ if(actualReceiverType instanceof ReferenceBinding) {
+ // record any selector match, for clients who may still need hint about possible method match
+ this.binding = scope.findMethod((ReferenceBinding)actualReceiverType, selector, new TypeBinding[]{}, this);
+ }
return null;
+ }
}
- if (this.actualReceiverType == null)
+ if (this.actualReceiverType == null) {
return null;
-
+ }
// base type cannot receive any message
if (this.actualReceiverType.isBaseType()) {
scope.problemReporter().errorNoMethodFor(this, this.actualReceiverType, argumentTypes);
@@ -274,28 +310,44 @@
}
if (!this.binding.isStatic()) {
// the "receiver" must not be a type, in other words, a NameReference that the TC has bound to a Type
- if (this.receiver instanceof NameReference) {
- if ((((NameReference) this.receiver).bits & Binding.TYPE) != 0) {
- scope.problemReporter().mustUseAStaticMethod(this, this.binding);
- return null;
+ if (receiver instanceof NameReference
+ && (((NameReference) receiver).bits & Binding.TYPE) != 0) {
+ scope.problemReporter().mustUseAStaticMethod(this, binding);
+ } else {
+ // compute generic cast if necessary
+ TypeBinding receiverErasure = this.actualReceiverType.erasure();
+ if (receiverErasure instanceof ReferenceBinding) {
+ ReferenceBinding match = ((ReferenceBinding)receiverErasure).findSuperTypeWithSameErasure(this.binding.declaringClass);
+ if (match == null) {
+ this.actualReceiverType = this.binding.declaringClass; // handle indirect inheritance thru variable secondary bound
+ }
}
+ receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
}
}
- if (this.arguments != null)
- for (int i = 0; i < this.arguments.length; i++)
- this.arguments[i].computeConversion(scope, this.binding.parameters[i], argumentTypes[i]);
+ checkInvocationArguments(scope, this.receiver, actualReceiverType, binding, this.arguments, argumentTypes, argsContainCast, this);
//-------message send that are known to fail at compile time-----------
- if (this.binding.isAbstract()) {
- if (this.receiver.isSuper()) {
- scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, this.binding);
- return null;
+ if (binding.isAbstract()) {
+ if (receiver.isSuper()) {
+ scope.problemReporter().cannotDireclyInvokeAbstractMethod(this, binding);
}
// abstract private methods cannot occur nor abstract static............
}
- if (isMethodUseDeprecated(this.binding, scope))
- scope.problemReporter().deprecatedMethod(this.binding, this);
+ if (isMethodUseDeprecated(binding, scope))
+ scope.problemReporter().deprecatedMethod(binding, this);
- return this.resolvedType = this.binding.returnType;
+ // from 1.5 compliance on, array#clone() returns the array type (but binding still shows Object)
+ if (actualReceiverType.isArrayType()
+ && this.binding.parameters == NoParameters
+ && scope.compilerOptions().complianceLevel >= JDK1_5
+ && CharOperation.equals(this.binding.selector, CLONE)) {
+ this.resolvedType = actualReceiverType;
+ } else {
+ TypeBinding returnType = this.binding.returnType;
+ if (returnType != null) returnType = returnType.capture(scope, this.sourceEnd);
+ this.resolvedType = returnType;
+ }
+ return this.resolvedType;
}
}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java
index 19034b9..3a20f88 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java
@@ -17,18 +17,18 @@
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
-import org.eclipse.jdt.internal.compiler.util.Util;
/**
* A parser for code snippets.
*/
public class CodeSnippetParser extends Parser implements EvaluationConstants {
int codeSnippetStart, codeSnippetEnd;
- boolean hasRecoveredOnExpression;
- int problemCountBeforeRecovery = 0;
- int lastStatement = -1; // end of last top level statement
-
EvaluationContext evaluationContext;
+ boolean hasRecoveredOnExpression;
+ int lastStatement = -1; // end of last top level statement
+ int lineSeparatorLength;
+
+ int problemCountBeforeRecovery = 0;
/**
* Creates a new code snippet parser.
*/
@@ -145,6 +145,11 @@
/* recovery */
recordLastStatementIfNeeded();
}
+protected void consumeEnhancedForStatement() {
+ super.consumeEnhancedForStatement();
+ /* recovery */
+ recordLastStatementIfNeeded();
+}
protected void consumeExpressionStatement() {
super.consumeExpressionStatement();
/* recovery */
@@ -245,6 +250,7 @@
/* recovery */
recordLastStatementIfNeeded();
}
+
/**
* In case emulating local variables, wrap the (recovered) statements inside a
* try statement so as to achieve local state commiting (copy local vars back to fields).
@@ -338,7 +344,7 @@
// MethodInvocation ::= Name '(' ArgumentListopt ')'
if (this.scanner.startPosition >= this.codeSnippetStart
- && this.scanner.startPosition <= this.codeSnippetEnd + 1 + Util.LINE_SEPARATOR_CHARS.length // 14838
+ && this.scanner.startPosition <= this.codeSnippetEnd + 1 + this.lineSeparatorLength // 14838
&& isTopLevelType()) {
// when the name is only an identifier...we have a message send to "this" (implicit)
@@ -374,12 +380,11 @@
m.receiver = new CodeSnippetSuperReference(m.sourceStart, this.endPosition, this.evaluationContext);
pushOnExpressionStack(m);
}
-
protected void consumePrimaryNoNewArrayThis() {
// PrimaryNoNewArray ::= 'this'
if (this.scanner.startPosition >= this.codeSnippetStart
- && this.scanner.startPosition <= this.codeSnippetEnd + 1 + Util.LINE_SEPARATOR_CHARS.length // 14838
+ && this.scanner.startPosition <= this.codeSnippetEnd + 1 + this.lineSeparatorLength // 14838
&& isTopLevelType()) {
pushOnExpressionStack(
new CodeSnippetThisReference(this.intStack[this.intPtr--], this.endPosition, this.evaluationContext, false));
@@ -443,7 +448,7 @@
// returned value intercepted by code snippet
// support have to be defined at toplevel only
if ((this.hasRecoveredOnExpression
- || (this.scanner.startPosition >= this.codeSnippetStart && this.scanner.startPosition <= this.codeSnippetEnd+1+Util.LINE_SEPARATOR_CHARS.length /* 14838*/))
+ || (this.scanner.startPosition >= this.codeSnippetStart && this.scanner.startPosition <= this.codeSnippetEnd+1+this.lineSeparatorLength /* 14838*/))
&& this.expressionLengthStack[this.expressionLengthPtr] != 0
&& isTopLevelType()) {
this.expressionLengthPtr--;
@@ -566,7 +571,7 @@
/* build a (unspecified) NameReference which may be qualified*/
if (this.scanner.startPosition >= this.codeSnippetStart
- && this.scanner.startPosition <= this.codeSnippetEnd+1+Util.LINE_SEPARATOR_CHARS.length /*14838*/){
+ && this.scanner.startPosition <= this.codeSnippetEnd+1+this.lineSeparatorLength /*14838*/){
int length;
NameReference ref;
if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
@@ -604,7 +609,7 @@
look for that it is not a type reference */
if (this.scanner.startPosition >= this.codeSnippetStart
- && this.scanner.startPosition <= this.codeSnippetEnd+1+Util.LINE_SEPARATOR_CHARS.length /*14838*/){
+ && this.scanner.startPosition <= this.codeSnippetEnd+1+this.lineSeparatorLength /*14838*/){
int length;
NameReference ref;
if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
@@ -675,10 +680,11 @@
* Records the scanner position if we're parsing a top level type.
*/
private void recordLastStatementIfNeeded() {
- if ((isTopLevelType()) && (this.scanner.startPosition <= this.codeSnippetEnd+Util.LINE_SEPARATOR_CHARS.length /*14838*/)) {
+ if ((isTopLevelType()) && (this.scanner.startPosition <= this.codeSnippetEnd+this.lineSeparatorLength /*14838*/)) {
this.lastStatement = this.scanner.startPosition;
}
}
+
protected void reportSyntaxErrors(boolean isDietParse, int oldFirstToken) {
if (!isDietParse) {
this.scanner.initialPosition = this.lastStatement;
@@ -687,7 +693,6 @@
}
super.reportSyntaxErrors(isDietParse, oldFirstToken);
}
-
/*
* A syntax error was detected. If a method is being parsed, records the number of errors and
* attempts to restart from the last statement by going for an expression.
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
index caa1c50..7e23576 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
@@ -237,7 +237,7 @@
}
codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id);
- codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+ codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
fieldStore(codeStream, lastFieldBinding, null, false);
} else {
@@ -273,7 +273,7 @@
}
codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id);
- codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+ codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
((CodeSnippetCodeStream) codeStream).generateEmulatedWriteAccessForField(lastFieldBinding);
}
}
@@ -524,7 +524,7 @@
&& !lastReceiverType.isArrayType()
&& fieldBinding.declaringClass != null // array.length
&& !fieldBinding.isConstantValue()) {
- CompilerOptions options = currentScope.environment().options;
+ CompilerOptions options = currentScope.compilerOptions();
if ((options.targetJDK >= ClassFileConstants.JDK1_2
&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || (index < 0 ? fieldBinding != binding : index > 0) || this.indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic())
&& fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
index b2512b2..c581a9d 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
@@ -556,13 +556,16 @@
invocationSite.setFieldIndex(currentIndex);
if (binding == null) {
if (currentIndex == length) // must be a type if its the last name, otherwise we have no idea if its a package or type
- return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), NotFound);
+ return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null, NotFound);
else
return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), NotFound);
}
if (binding instanceof ReferenceBinding) {
if (!binding.isValidBinding())
- return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), binding.problemId());
+ return new ProblemReferenceBinding(
+ CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
+ binding.problemId());
if (!this.canBeSeenByForCodeSnippet((ReferenceBinding) binding, receiverType))
return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), (ReferenceBinding) binding, NotVisible);
break foundType;
@@ -571,7 +574,7 @@
}
// It is illegal to request a PACKAGE from this method.
- return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), NotFound);
+ return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null, NotFound);
}
// know binding is now a ReferenceBinding
@@ -581,19 +584,22 @@
invocationSite.setFieldIndex(currentIndex);
if ((binding = findFieldForCodeSnippet(typeBinding, nextName, invocationSite)) != null) {
if (!binding.isValidBinding())
- return new ProblemFieldBinding(((FieldBinding)binding).declaringClass, CharOperation.subarray(compoundName, 0, currentIndex), binding.problemId());
+ return new ProblemFieldBinding((FieldBinding)binding, CharOperation.subarray(compoundName, 0, currentIndex), binding.problemId());
break; // binding is now a field
}
if ((binding = findMemberType(nextName, typeBinding)) == null)
return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), typeBinding, NotFound);
if (!binding.isValidBinding())
- return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), binding.problemId());
+ return new ProblemReferenceBinding(
+ CharOperation.subarray(compoundName, 0, currentIndex),
+ null, // TODO should improve
+ binding.problemId());
}
if ((mask & Binding.FIELD) != 0 && (binding instanceof FieldBinding)) { // was looking for a field and found a field
FieldBinding field = (FieldBinding) binding;
if (!field.isStatic())
- return new ProblemFieldBinding(field.declaringClass, CharOperation.subarray(compoundName, 0, currentIndex), NonStaticReferenceInStaticContext);
+ return new ProblemFieldBinding(field, CharOperation.subarray(compoundName, 0, currentIndex), NonStaticReferenceInStaticContext);
return binding;
}
if ((mask & Binding.TYPE) != 0 && (binding instanceof ReferenceBinding)) { // was looking for a type and found a type
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
index e73168b..c5ce8fe 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
@@ -110,13 +110,16 @@
// optimizing assignment like: i = i + 1 or i = 1 + i
if (assignment.expression.isCompactableOperation()) {
BinaryExpression operation = (BinaryExpression) assignment.expression;
+ int operator = (operation.bits & OperatorMASK) >> OperatorSHIFT;
SingleNameReference variableReference;
if ((operation.left instanceof SingleNameReference) && ((variableReference = (SingleNameReference) operation.left).binding == this.binding)) {
// i = i + value, then use the variable on the right hand side, since it has the correct implicit conversion
- variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[WRITE], operation.right, (operation.bits & OperatorMASK) >> OperatorSHIFT, operation.left.implicitConversion /*should be equivalent to no conversion*/, valueRequired);
+ variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[WRITE], operation.right, operator, operation.implicitConversion, valueRequired);
+ if (valueRequired) {
+ codeStream.generateImplicitConversion(assignment.implicitConversion);
+ }
return;
}
- int operator = (operation.bits & OperatorMASK) >> OperatorSHIFT;
if ((operation.right instanceof SingleNameReference)
&& ((operator == PLUS) || (operator == MULTIPLY)) // only commutative operations
&& ((variableReference = (SingleNameReference) operation.right).binding == this.binding)
@@ -124,7 +127,10 @@
&& (((operation.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString) // exclude string concatenation which would occur backwards
&& (((operation.right.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString)) { // exclude string concatenation which would occur backwards
// i = value + i, then use the variable on the right hand side, since it has the correct implicit conversion
- variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[WRITE], operation.left, operator, operation.right.implicitConversion /*should be equivalent to no conversion*/, valueRequired);
+ variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[WRITE], operation.left, operator, operation.implicitConversion, valueRequired);
+ if (valueRequired) {
+ codeStream.generateImplicitConversion(assignment.implicitConversion);
+ }
return;
}
}
@@ -454,7 +460,7 @@
}
codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
codeStream.sendOperator(postIncrement.operator, fieldBinding.type.id);
- codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+ codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
fieldStore(codeStream, fieldBinding, null, false);
} else {
if (fieldBinding.isStatic()) {
@@ -500,7 +506,7 @@
}
codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
codeStream.sendOperator(postIncrement.operator, fieldBinding.type.id);
- codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+ codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
((CodeSnippetCodeStream) codeStream).generateEmulatedWriteAccessForField(fieldBinding);
}
return;
@@ -527,7 +533,7 @@
}
codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
codeStream.sendOperator(postIncrement.operator, localBinding.type.id);
- codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
+ codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
codeStream.store(localBinding, false);
}
@@ -584,7 +590,7 @@
if (fieldBinding.declaringClass != this.delegateThis.type
&& fieldBinding.declaringClass != null // array.length
&& !fieldBinding.isConstantValue()) {
- CompilerOptions options = currentScope.environment().options;
+ CompilerOptions options = currentScope.compilerOptions();
if ((options.targetJDK >= ClassFileConstants.JDK1_2
&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic())
&& fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
index b2e7dbc..c63506e 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
@@ -17,7 +17,6 @@
import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;
-import org.eclipse.jdt.internal.compiler.util.Util;
/**
* Maps back and forth a code snippet to a compilation unit.
@@ -59,7 +58,7 @@
/**
* Rebuild source in presence of external local variables
*/
- public CodeSnippetToCuMapper(char[] codeSnippet, char[] packageName, char[][] imports, char[] className, char[] varClassName, char[][] localVarNames, char[][] localVarTypeNames, int[] localVarModifiers, char[] declaringTypeName) {
+ public CodeSnippetToCuMapper(char[] codeSnippet, char[] packageName, char[][] imports, char[] className, char[] varClassName, char[][] localVarNames, char[][] localVarTypeNames, int[] localVarModifiers, char[] declaringTypeName, String lineSeparator) {
this.codeSnippet = codeSnippet;
this.snippetPackageName = packageName;
this.snippetImports = imports;
@@ -69,16 +68,16 @@
this.localVarTypeNames = localVarTypeNames;
this.localVarModifiers = localVarModifiers;
this.snippetDeclaringTypeName = declaringTypeName;
- this.buildCUSource();
+ this.buildCUSource(lineSeparator);
}
-private void buildCUSource() {
+private void buildCUSource(String lineSeparator) {
StringBuffer buffer = new StringBuffer();
// package declaration
if (this.snippetPackageName != null && this.snippetPackageName.length != 0) {
buffer.append("package "); //$NON-NLS-1$
buffer.append(this.snippetPackageName);
- buffer.append(";").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
+ buffer.append(";").append(lineSeparator); //$NON-NLS-1$
this.lineNumberOffset++;
}
@@ -87,7 +86,7 @@
for (int i = 0; i < imports.length; i++) {
buffer.append("import "); //$NON-NLS-1$
buffer.append(imports[i]);
- buffer.append(';').append(Util.LINE_SEPARATOR);
+ buffer.append(';').append(lineSeparator);
this.lineNumberOffset++;
}
@@ -105,7 +104,7 @@
buffer.append("."); //$NON-NLS-1$
buffer.append(ROOT_CLASS_NAME);
}
- buffer.append(" {").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
+ buffer.append(" {").append(lineSeparator); //$NON-NLS-1$
this.lineNumberOffset++;
if (this.snippetDeclaringTypeName != null){
@@ -113,7 +112,7 @@
buffer.append(this.snippetDeclaringTypeName);
buffer.append(" "); //$NON-NLS-1$
buffer.append(DELEGATE_THIS); // val$this
- buffer.append(';').append(Util.LINE_SEPARATOR);
+ buffer.append(';').append(lineSeparator);
this.lineNumberOffset++;
}
// add some storage location for local variable persisted state
@@ -124,22 +123,22 @@
buffer.append(" "); //$NON-NLS-1$
buffer.append(LOCAL_VAR_PREFIX); // val$...
buffer.append(this.localVarNames[i]);
- buffer.append(';').append(Util.LINE_SEPARATOR);
+ buffer.append(';').append(lineSeparator);
this.lineNumberOffset++;
}
}
// run() method declaration
- buffer.append("public void run() throws Throwable {").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
+ buffer.append("public void run() throws Throwable {").append(lineSeparator); //$NON-NLS-1$
this.lineNumberOffset++;
this.startPosOffset = buffer.length();
buffer.append(this.codeSnippet);
// a line separator is required after the code snippet source code
// in case the code snippet source code ends with a line comment
// http://dev.eclipse.org/bugs/show_bug.cgi?id=14838
- buffer.append(Util.LINE_SEPARATOR).append('}').append(Util.LINE_SEPARATOR);
+ buffer.append(lineSeparator).append('}').append(lineSeparator);
// end of class declaration
- buffer.append('}').append(Util.LINE_SEPARATOR);
+ buffer.append('}').append(lineSeparator);
// store result
int length = buffer.length();
@@ -191,9 +190,9 @@
}
};
}
-public char[] getCUSource() {
+public char[] getCUSource(String lineSeparator) {
if (this.cuSource == null) {
- buildCUSource();
+ buildCUSource(lineSeparator);
}
return this.cuSource;
}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java
index 893caf2..8119fd0 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java
@@ -15,7 +15,6 @@
import org.eclipse.jdt.core.CompletionRequestor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.compiler.*;
-import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.internal.codeassist.CompletionEngine;
import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;
import org.eclipse.jdt.internal.codeassist.SelectionEngine;
@@ -51,6 +50,7 @@
boolean varsChanged;
VariablesInfo installedVars;
IBinaryType codeSnippetBinary;
+ String lineSeparator;
/* do names implicitly refer to a given type */
char[] declaringTypeName;
@@ -72,6 +72,7 @@
this.varsChanged = true;
this.isStatic = true;
this.isConstructorCall = false;
+ this.lineSeparator = org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR; // default value
}
/**
* Returns the global variables of this evaluation context in the order they were created in.
@@ -107,14 +108,15 @@
this.localVariableNames,
this.localVariableTypeNames,
this.localVariableModifiers,
- this.declaringTypeName
+ this.declaringTypeName,
+ this.lineSeparator
);
ICompilationUnit sourceUnit = new ICompilationUnit() {
public char[] getFileName() {
return CharOperation.concat(className, Util.defaultJavaExtension().toCharArray());
}
public char[] getContents() {
- return mapper.getCUSource();
+ return mapper.getCUSource(EvaluationContext.this.lineSeparator);
}
public char[] getMainTypeName() {
return className;
@@ -511,14 +513,15 @@
this.localVariableNames,
this.localVariableTypeNames,
this.localVariableModifiers,
- this.declaringTypeName
+ this.declaringTypeName,
+ this.lineSeparator
);
ICompilationUnit sourceUnit = new ICompilationUnit() {
public char[] getFileName() {
return CharOperation.concat(className, Util.defaultJavaExtension().toCharArray());
}
public char[] getContents() {
- return mapper.getCUSource();
+ return mapper.getCUSource(EvaluationContext.this.lineSeparator);
}
public char[] getMainTypeName() {
return className;
@@ -540,6 +543,12 @@
this.varsChanged = true; // this may change the visibility of the variable's types
}
/**
+ * Sets the line separator used by this evaluation context.
+ */
+public void setLineSeparator(String lineSeparator) {
+ this.lineSeparator = lineSeparator;
+}
+/**
* Sets the dot-separated name of the package code snippets are ran into.
* The default package name is an empty array.
*/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java
index f75da9a..b6db9b3 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java
@@ -22,7 +22,6 @@
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
-import org.eclipse.jdt.internal.compiler.util.Util;
/**
* A variables evaluator compiles the global variables of an evaluation context and returns
@@ -190,7 +189,7 @@
if (packageName.length != 0) {
buffer.append("package "); //$NON-NLS-1$
buffer.append(packageName);
- buffer.append(';').append(Util.LINE_SEPARATOR);
+ buffer.append(';').append(this.context.lineSeparator);
lineNumberOffset++;
}
@@ -199,7 +198,7 @@
for (int i = 0; i < imports.length; i++) {
buffer.append("import "); //$NON-NLS-1$
buffer.append(imports[i]);
- buffer.append(';').append(Util.LINE_SEPARATOR);
+ buffer.append(';').append(this.context.lineSeparator);
lineNumberOffset++;
}
@@ -210,7 +209,7 @@
buffer.append(PACKAGE_NAME);
buffer.append("."); //$NON-NLS-1$
buffer.append(ROOT_CLASS_NAME);
- buffer.append(" {").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
+ buffer.append(" {").append(this.context.lineSeparator); //$NON-NLS-1$
lineNumberOffset++;
this.startPosOffset = buffer.length();
@@ -225,12 +224,12 @@
buffer.append(" "); //$NON-NLS-1$
char[] varName = var.name;
buffer.append(varName);
- buffer.append(';').append(Util.LINE_SEPARATOR);
+ buffer.append(';').append(this.context.lineSeparator);
lineNumberOffset++;
}
// field initializations
- buffer.append("\tstatic {").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
+ buffer.append("\tstatic {").append(this.context.lineSeparator); //$NON-NLS-1$
lineNumberOffset++;
for (int i = 0; i < this.context.variableCount; i++){
GlobalVariable var = vars[i];
@@ -240,7 +239,7 @@
// Initialize with initializer if there was no previous value
char[] initializer = var.initializer;
if (initializer != null) {
- buffer.append("\t\ttry {").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
+ buffer.append("\t\ttry {").append(this.context.lineSeparator); //$NON-NLS-1$
lineNumberOffset++;
var.initializerLineStart = lineNumberOffset;
buffer.append("\t\t\t"); //$NON-NLS-1$
@@ -250,10 +249,10 @@
var.initExpressionStart = buffer.length();
buffer.append(initializer);
lineNumberOffset += numberOfCRs(initializer);
- buffer.append(';').append(Util.LINE_SEPARATOR);
- buffer.append("\t\t} catch (Throwable e) {").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
- buffer.append("\t\t\te.printStackTrace();").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
- buffer.append("\t\t}").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
+ buffer.append(';').append(this.context.lineSeparator);
+ buffer.append("\t\t} catch (Throwable e) {").append(this.context.lineSeparator); //$NON-NLS-1$
+ buffer.append("\t\t\te.printStackTrace();").append(this.context.lineSeparator); //$NON-NLS-1$
+ buffer.append("\t\t}").append(this.context.lineSeparator); //$NON-NLS-1$
lineNumberOffset += 4; // 4 CRs
}
} else {
@@ -269,14 +268,14 @@
buffer.append(installedVars.className);
buffer.append("."); //$NON-NLS-1$
buffer.append(varName);
- buffer.append(';').append(Util.LINE_SEPARATOR);
+ buffer.append(';').append(this.context.lineSeparator);
lineNumberOffset++;
}
}
- buffer.append("\t}").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
+ buffer.append("\t}").append(this.context.lineSeparator); //$NON-NLS-1$
// end of class declaration
- buffer.append('}').append(Util.LINE_SEPARATOR);
+ buffer.append('}').append(this.context.lineSeparator);
// return result
int length = buffer.length();
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
index 25823a2..caf50f4 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
@@ -808,7 +808,7 @@
/**
* <pre>
- * FORMATTER / Option to insert a new line after the opening brace in an array initializer
+ * FORMATTER / Option to insert a new line after an annotation
* - option id: "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation"
* - possible values: { INSERT, DO_NOT_INSERT }
* - default: INSERT
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/package.html b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/package.html
new file mode 100644
index 0000000..90588e9
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/package.html
@@ -0,0 +1,19 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="IBM">
+ <title>Package-level Javadoc</title>
+</head>
+<body>
+The code formatter is the set of classes that are used to format Java code.
+
+<h2>
+Package Specification</h2>
+
+<p>This package contains classes to format Java code.
+The principal classes are {@link org.eclipse.jdt.core.formatter.CodeFormatter CodeFormatter} and
+{@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants DefaultCodeFormatterConstants}.
+</p>
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java
index 2211187..028d6ea 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java
@@ -311,6 +311,8 @@
if (currentField.declarationSourceStart == ((FieldDeclaration) previousMergedNode).declarationSourceStart) {
// we create a multi field declaration
mergedNodes.set(mergedNodes.size() - 1, new MultiFieldDeclaration(new FieldDeclaration[]{ (FieldDeclaration)previousMergedNode, currentField}));
+ } else {
+ mergedNodes.add(currentNode);
}
} else {
mergedNodes.add(currentNode);
@@ -1328,6 +1330,28 @@
if (numberOfParens > 0) {
manageOpeningParenthesizedExpression(currentMessageSend, numberOfParens);
}
+ TypeReference[] typeArguments = currentMessageSend.typeArguments;
+ if (typeArguments != null) {
+ this.scribe.printNextToken(TerminalTokens.TokenNameLESS, this.preferences.insert_space_before_opening_angle_bracket_in_type_arguments);
+ if (this.preferences.insert_space_after_opening_angle_bracket_in_type_arguments) {
+ this.scribe.space();
+ }
+ int length = typeArguments.length;
+ for (int j = 0; j < length - 1; j++) {
+ typeArguments[j].traverse(this, scope);
+ this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_type_arguments);
+ if (this.preferences.insert_space_after_comma_in_type_arguments) {
+ this.scribe.space();
+ }
+ }
+ typeArguments[length - 1].traverse(this, scope);
+ if (isClosingGenericToken()) {
+ this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_type_arguments);
+ }
+ if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) {
+ this.scribe.space();
+ }
+ }
ASTNode[] arguments = currentMessageSend.arguments;
this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier); // selector
this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation);
@@ -1486,7 +1510,7 @@
private void formatLocalDeclaration(LocalDeclaration localDeclaration, BlockScope scope, boolean insertSpaceBeforeComma, boolean insertSpaceAfterComma) {
if (!isMultipleLocalDeclaration(localDeclaration)) {
- if (localDeclaration.modifiers != NO_MODIFIERS) {
+ if (localDeclaration.modifiers != NO_MODIFIERS || localDeclaration.annotations != null) {
this.scribe.printComment();
this.scribe.printModifiers(localDeclaration.annotations, this);
this.scribe.space();
@@ -1987,16 +2011,15 @@
int token;
while ((token = this.localScanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
switch(token) {
- case TerminalTokens.TokenNameRBRACKET://166
+ case TerminalTokens.TokenNameRBRACKET:
dimensions++;
break;
- case TerminalTokens.TokenNameIdentifier ://90
- case TerminalTokens.TokenNameLBRACE ://90
- case TerminalTokens.TokenNameLPAREN :
- case TerminalTokens.TokenNameCOMMA ://90
- case TerminalTokens.TokenNameEQUAL ://167
- case TerminalTokens.TokenNameSEMICOLON ://64
- case TerminalTokens.TokenNameRPAREN : //86
+ case TerminalTokens.TokenNameCOMMENT_BLOCK :
+ case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+ case TerminalTokens.TokenNameCOMMENT_LINE :
+ case TerminalTokens.TokenNameLBRACKET :
+ break;
+ default:
return dimensions;
}
}
@@ -2268,7 +2291,7 @@
*/
public boolean visit(Argument argument, BlockScope scope) {
- if (argument.modifiers != NO_MODIFIERS) {
+ if (argument.modifiers != NO_MODIFIERS || argument.annotations != null) {
this.scribe.printComment();
this.scribe.printModifiers(argument.annotations, this);
this.scribe.space();
@@ -2475,7 +2498,7 @@
if (numberOfParens > 0) {
manageOpeningParenthesizedExpression(arrayQualifiedTypeReference, numberOfParens);
}
- this.scribe.printQualifiedReference(arrayQualifiedTypeReference.sourceEnd);
+ this.scribe.printArrayQualifiedReference(arrayQualifiedTypeReference.tokens.length, arrayQualifiedTypeReference.sourceEnd);
int dimensions = getDimensions();
if (dimensions != 0) {
for (int i = 0; i < dimensions; i++) {
@@ -2500,7 +2523,7 @@
if (numberOfParens > 0) {
manageOpeningParenthesizedExpression(arrayQualifiedTypeReference, numberOfParens);
}
- this.scribe.printQualifiedReference(arrayQualifiedTypeReference.sourceEnd);
+ this.scribe.printArrayQualifiedReference(arrayQualifiedTypeReference.tokens.length, arrayQualifiedTypeReference.sourceEnd);
int dimensions = getDimensions();
if (dimensions != 0) {
for (int i = 0; i < dimensions; i++) {
@@ -3790,7 +3813,12 @@
if (this.preferences.insert_space_after_colon_in_labeled_statement) {
this.scribe.space();
}
- labeledStatement.statement.traverse(this, scope);
+ final Statement statement = labeledStatement.statement;
+ statement.traverse(this, scope);
+ if (statement instanceof Expression) {
+ this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
+ this.scribe.printTrailingComment();
+ }
return false;
}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
index 525bd59..e27f3b7 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
@@ -333,21 +333,25 @@
}
ProbingScanner.setSource((char[]) null);
+ // probe for expression
Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
if (expression != null) {
return internalFormatExpression(source, indentationLevel, lineSeparator, expression, offset, length);
}
+ // probe for body declarations (fields, methods, constructors)
ASTNode[] bodyDeclarations = this.codeSnippetParsingUtil.parseClassBodyDeclarations(source.toCharArray(), getDefaultCompilerOptions(), true);
if (bodyDeclarations != null) {
return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, offset, length);
}
+ // probe for statements
ConstructorDeclaration constructorDeclaration = this.codeSnippetParsingUtil.parseStatements(source.toCharArray(), getDefaultCompilerOptions(), true);
if (constructorDeclaration.statements != null) {
return internalFormatStatements(source, indentationLevel, lineSeparator, constructorDeclaration, offset, length);
}
+ // this has to be a compilation unit
return formatCompilationUnit(source, indentationLevel, lineSeparator, offset, length);
}
}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
index a42e291..c7fd854 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
@@ -1206,7 +1206,7 @@
hasModifiers = true;
this.print(this.scanner.getRawTokenSource(), !isFirstModifier);
isFirstModifier = false;
- currentTokenStartPosition = this.scanner.getCurrentTokenStartPosition();
+ currentTokenStartPosition = this.scanner.currentPosition;
break;
case TerminalTokens.TokenNameAT :
hasModifiers = true;
@@ -1352,6 +1352,50 @@
}
}
+ public void printArrayQualifiedReference(int numberOfTokens, int sourceEnd) {
+ int currentTokenStartPosition = this.scanner.currentPosition;
+ int numberOfIdentifiers = 0;
+ try {
+ do {
+ this.printComment();
+ switch(this.currentToken = this.scanner.getNextToken()) {
+ case TerminalTokens.TokenNameEOF :
+ return;
+ case TerminalTokens.TokenNameWHITESPACE :
+ addDeleteEdit(this.scanner.getCurrentTokenStartPosition(), this.scanner.getCurrentTokenEndPosition());
+ currentTokenStartPosition = this.scanner.currentPosition;
+ break;
+ case TerminalTokens.TokenNameCOMMENT_BLOCK :
+ case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+ this.printBlockComment(this.scanner.getRawTokenSource(), false);
+ currentTokenStartPosition = this.scanner.currentPosition;
+ break;
+ case TerminalTokens.TokenNameCOMMENT_LINE :
+ this.printCommentLine(this.scanner.getRawTokenSource());
+ currentTokenStartPosition = this.scanner.currentPosition;
+ break;
+ case TerminalTokens.TokenNameIdentifier :
+ this.print(this.scanner.getRawTokenSource(), false);
+ currentTokenStartPosition = this.scanner.currentPosition;
+ if (++ numberOfIdentifiers == numberOfTokens) {
+ this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1);
+ return;
+ }
+ break;
+ case TerminalTokens.TokenNameDOT :
+ this.print(this.scanner.getRawTokenSource(), false);
+ currentTokenStartPosition = this.scanner.currentPosition;
+ break;
+ default:
+ this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1);
+ return;
+ }
+ } while (this.scanner.currentPosition <= sourceEnd);
+ } catch(InvalidInputException e) {
+ throw new AbortFormatting(e);
+ }
+ }
+
public void printQualifiedReference(int sourceEnd) {
int currentTokenStartPosition = this.scanner.currentPosition;
try {
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocRegion.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocRegion.java
index 5767dc7..e38dde6 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocRegion.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocRegion.java
@@ -197,10 +197,19 @@
ILineTracker tracker= new DefaultLineTracker();
String patch= indentation + MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX;
+ // remove trailing spaces
+ int i= snippet.length();
+ while (i > 0 && ' ' == snippet.charAt(i-1))
+ i--;
+ snippet= snippet.substring(0, i);
+
buffer.setLength(0);
- buffer.append(getDelimiter());
+ String lineDelimiter= getDelimiter();
+ if (lineDelimiter != null && snippet.indexOf(lineDelimiter) != 0)
+ buffer.append(lineDelimiter);
buffer.append(convertJava2Html(snippet));
- buffer.append(getDelimiter());
+ if (lineDelimiter != null && snippet.lastIndexOf(lineDelimiter) != snippet.length() - lineDelimiter.length())
+ buffer.append(lineDelimiter);
tracker.set(buffer.toString());
for (int line= tracker.getNumberOfLines() - 1; line > 0; line--)
diff --git a/org.eclipse.jdt.core/grammar/java_1_5.g b/org.eclipse.jdt.core/grammar/java_1_5.g
index 375240b..53e1f2a 100644
--- a/org.eclipse.jdt.core/grammar/java_1_5.g
+++ b/org.eclipse.jdt.core/grammar/java_1_5.g
@@ -1582,7 +1582,7 @@
/.$putCase consumeEnumConstantHeaderName(); $break ./
/:$readableName EnumConstantHeaderName:/
-EnumConstantHeader ::= EnumConstantHeaderName Argumentsopt
+EnumConstantHeader ::= EnumConstantHeaderName ForceNoDiet Argumentsopt RestoreDiet
/.$putCase consumeEnumConstantHeader(); $break ./
/:$readableName EnumConstantHeader:/
@@ -2050,7 +2050,8 @@
AnnotationTypeMemberDeclarationsopt ::= $empty
/.$putCase consumeEmptyAnnotationTypeMemberDeclarationsopt() ; $break ./
/:$compliance 1.5:/
-AnnotationTypeMemberDeclarationsopt -> AnnotationTypeMemberDeclarations
+AnnotationTypeMemberDeclarationsopt ::= NestedType AnnotationTypeMemberDeclarations
+/.$putCase consumeAnnotationTypeMemberDeclarationsopt() ; $break ./
/:$readableName AnnotationTypeMemberDeclarations:/
/:$compliance 1.5:/
diff --git a/org.eclipse.jdt.core/jdt_core_style.css b/org.eclipse.jdt.core/jdt_core_style.css
new file mode 100644
index 0000000..f9a680a
--- /dev/null
+++ b/org.eclipse.jdt.core/jdt_core_style.css
@@ -0,0 +1,18 @@
+@charset "iso-8859-1";
+TD.title1
+{
+font-family: "Verdana", "Arial", "Helvetica";
+}
+B.title1
+{
+font-family:"Times New Roman";
+}
+TD.title2
+{
+font-family: "Arial", "Helvetica", "sans-serif";
+color: #8080ff
+}
+TD.title3
+{
+font-family: "Arial", "Helvetica", "sans-serif";
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BindingKey.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BindingKey.java
index 1c7c5d2..2196a29 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BindingKey.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BindingKey.java
@@ -175,18 +175,6 @@
}
/**
- * Returns the declaring type signature of the element represented by this binding key.
- * Returns the signature of the element if it is a type.
- *
- * @return the declaring type signature
- */
- public String getDeclaringTypeSignature() {
- KeyToSignature keyToSignature = new KeyToSignature(this.key, KeyToSignature.DECLARING_TYPE);
- keyToSignature.parse();
- return keyToSignature.signature.toString();
- }
-
- /**
* Returns the type argument signatures of the element represented by this binding key.
* If this binding key doesn't represent a parameterized type or a parameterized method,
* returns an empty array.
@@ -233,11 +221,15 @@
}
/**
- * Transforms this binding key into a signature.
+ * Internal method.
+ * <p>
+ * This method transforms this binding key into a signature.
+ * This method is not intended to be called by clients.
+ * </p>
*
* @return the signature for this binding key
*/
- public String toSignature() {
+ public String internalToSignature() {
KeyToSignature keyToSignature = new KeyToSignature(this.key, KeyToSignature.SIGNATURE);
keyToSignature.parse();
return keyToSignature.signature.toString();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
index 9c210fb..74a3813 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
@@ -928,8 +928,8 @@
* <li><code>KEYWORD</code> - the keyword</li>
* <li><code>LABEL_REF</code> - the name of the label</li>
* <li><code>LOCAL_VARIABLE_REF</code> - the name of the local variable</li>
- * <li><code>METHOD_REF</code> - the name of the method</li>
- * <li><code>METHOD_DECLARATION</code> - the name of the method</li>
+ * <li><code>METHOD_REF</code> - the name of the method (the type simple name for constructor)</li>
+ * <li><code>METHOD_DECLARATION</code> - the name of the method (the type simple name for constructor)</li>
* <li><code>VARIABLE_DECLARATION</code> - the name of the variable</li>
* <li><code>POTENTIAL_METHOD_DECLARATION</code> - the name of the method</li>
* </ul>
@@ -947,7 +947,7 @@
/**
- * Sets the simple name of the method, field,
+ * Sets the simple name of the method (type simple name for constructor), field,
* member, or variable relevant in the context, or
* <code>null</code> if none.
* <p>
@@ -1359,37 +1359,52 @@
switch(this.completionKind) {
case ANONYMOUS_CLASS_DECLARATION:
- this.parameterNames = this.findMethodParameterNames(
- this.declarationPackageName,
- this.declarationTypeName,
- CharOperation.lastSegment(this.declarationTypeName, '.'),
- this.parameterPackageNames,
- this.parameterTypeNames);
+ try {
+ this.parameterNames = this.findMethodParameterNames(
+ this.declarationPackageName,
+ this.declarationTypeName,
+ CharOperation.lastSegment(this.declarationTypeName, '.'),
+ Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature));
+ } catch(IllegalArgumentException e) {
+ // protection for invalid signature
+ if(this.parameterTypeNames != null) {
+ this.parameterNames = this.createDefaultParameterNames(this.parameterTypeNames.length);
+ } else {
+ this.parameterNames = null;
+ }
+ }
break;
case METHOD_REF:
- this.parameterNames = this.findMethodParameterNames(
- this.declarationPackageName,
- this.declarationTypeName,
- this.name,
- this.parameterPackageNames,
- this.parameterTypeNames);
- //this.parameterNames = this.findMethodParameterNames(
- // this.declarationSignature,
- // this.name,
- // Signature.getParameterTypes(this.getSignature()));
+ try {
+ this.parameterNames = this.findMethodParameterNames(
+ this.declarationPackageName,
+ this.declarationTypeName,
+ this.name,
+ Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature));
+ } catch(IllegalArgumentException e) {
+ // protection for invalid signature
+ if(this.parameterTypeNames != null) {
+ this.parameterNames = this.createDefaultParameterNames(this.parameterTypeNames.length);
+ } else {
+ this.parameterNames = null;
+ }
+ }
break;
case METHOD_DECLARATION:
- this.parameterNames = this.findMethodParameterNames(
- this.declarationPackageName,
- this.declarationTypeName,
- this.name,
- this.parameterPackageNames,
- this.parameterTypeNames);
- //char[][] parameterTypes = Signature.getParameterTypes(this.getSignature();
- ///this.parameterNames = this.findMethodParameterNames(
- // this.declarationSignature,
- // this.name,
- // parameterTypes);
+ try {
+ this.parameterNames = this.findMethodParameterNames(
+ this.declarationPackageName,
+ this.declarationTypeName,
+ this.name,
+ Signature.getParameterTypes(this.originalSignature == null ? this.signature : this.originalSignature));
+ } catch(IllegalArgumentException e) {
+ // protection for invalid signature
+ if(this.parameterTypeNames != null) {
+ this.parameterNames = this.createDefaultParameterNames(this.parameterTypeNames.length);
+ } else {
+ this.parameterNames = null;
+ }
+ }
if(this.parameterNames != null) {
this.updateCompletion = true;
}
@@ -1438,4 +1453,26 @@
public int getAccessibility() {
return this.accessibility;
}
+
+ /**
+ * Returns whether this proposal is a constructor.
+ * <p>
+ * This field is available for the following kinds of
+ * completion proposals:
+ * <ul>
+ * <li><code>METHOD_REF</code> - return <code>true</code>
+ * if the referenced method is a constructor</li>
+ * <li><code>METHOD_DECLARATION</code> - return <code>true</code>
+ * if the declared method is a constructor</li>
+ * </ul>
+ * For kinds of completion proposals, this method returns
+ * <code>false</code>.
+ * </p>
+ *
+ * @return <code>true</code> if the proposal is a constructor.
+ * @since 3.1
+ */
+ public boolean isConstructor() {
+ return this.isConstructor;
+ }
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java
index fde348e..d873606 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java
@@ -14,10 +14,10 @@
import org.eclipse.core.resources.*;
import org.eclipse.jdt.core.compiler.*;
-import org.eclipse.jdt.core.compiler.InvalidInputException;
-import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.Util;
@@ -401,4 +401,39 @@
String argumentsString = problemMarker.getAttribute(IJavaModelMarker.ARGUMENTS, null);
return Util.getProblemArgumentsFromMarker(argumentsString);
}
+
+ /**
+ * Returns a token which can be used to suppress a given warning using
+ * <code>@SuppressWarnings</code> annotation, for a given problem ID
+ * ({@link IProblem }). If a particular problem is not suppressable,
+ * <code>null</code> will be returned.
+ * <p>
+ * <b>Note:</b> <code>@SuppressWarnings</code> can only suppress warnings,
+ * which means that if some problems got promoted to ERROR using custom compiler
+ * settings ({@link IJavaProject#setOption(String, String)}), the
+ * <code>@SuppressWarnings</code> annotation will be ineffective.
+ * </p>
+ * <p>
+ * <b>Note:</b> <code>@SuppressWarnings</code> can be argumented with
+ * <code>"all"</code> so as to suppress all possible warnings at once.
+ * </p>
+ * <p>
+ * <b>Note:</b> The tokens returned are not necessarily standardized across Java
+ * compilers. If you were to use one of these tokens in an @SuppressWarnings
+ * annotation in the Java source code, the effects (if any) may vary from
+ * compiler to compiler.
+ * </p>
+ * @param problemID
+ * the ID of a given warning to suppress
+ * @return a String which can be used in <code>@SuppressWarnings</code> annotation,
+ * or <code>null</code> if unable to suppress this warning.
+ * @since 3.1
+ */
+ public static String getWarningToken(int problemID){
+ long irritant = ProblemReporter.getIrritant(problemID);
+ if (irritant != 0) {
+ return CompilerOptions.warningTokenFromIrritant(irritant);
+ }
+ return null;
+ }
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAccessRule.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAccessRule.java
index c790e0d..9079343 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAccessRule.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAccessRule.java
@@ -31,10 +31,13 @@
* Note this is different from inclusion and exclusion patterns on source classpath entries,
* where a source file that is excluded is not even compiled.
* Files patterns look like relative file paths with wildcards and are interpreted relative
- * to each entry's path.
+ * to each entry's path.
* File patterns are case-sensitive and they can contain '**', '*' or '?' wildcards (see
* {@link IClasspathEntry#getExclusionPatterns()} for the full description
* of their syntax and semantics).
+ * Note that file patterns must not include the file extension.
+ * <code>com/xyz/tests/MyClass</code> is a valid file pattern, whereas
+ * <code>com/xyz/tests/MyClass.class</code> is not valid.
* </p>
* <p>
* For example, if one of the entry path is <code>/Project/someLib.jar</code>,
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java
index 3f5be18..e714fac 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java
@@ -139,9 +139,7 @@
* included in the result.
* <p>
* Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
+ * new language features of J2SE 5.0.
* </p>
*
* @param name the name of the import declaration to add as defined by JLS2 7.5. (For example: <code>"java.io.File"</code> or
@@ -514,10 +512,6 @@
* creation of the DOM AST was not requested, or if the requested level of AST
* API is not supported, or if the working copy was already consistent.
* </p>
- * <b>NOTE:</b>In Eclipse 3.0, there is no reconciler support for
- * level AST.JLS3. This support is planned for the follow-on release of
- * Eclipse which includes support for J2SE 1.5.
- * </p>
*
* @param astLevel either {@link #NO_AST} if no AST is wanted,
* or the {@linkplain AST#newAST(int) AST API level} of the AST if one is wanted
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
index 422c51a..c73c501 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
@@ -115,7 +115,7 @@
* - internal to the workbench: "/Project/src"
* - external to the workbench: "c:/jdk/classes.zip/java/lang"
* @param path the given absolute path
- * @exception JavaModelException if this element does not exist or if an
+ * @exception JavaModelException if this project does not exist or if an
* exception occurs while accessing its corresponding resource
* @return the first existing package fragment on this project's classpath
* whose path matches the given (absolute) path, or <code>null</code> if none
@@ -131,7 +131,7 @@
* - internal to the workbench: "/Compiler/src"
* - external to the workbench: "c:/jdk/classes.zip"
* @param path the given absolute path
- * @exception JavaModelException if this element does not exist or if an
+ * @exception JavaModelException if this project does not exist or if an
* exception occurs while accessing its corresponding resource
* @return the existing package fragment root on this project's classpath
* whose path matches the given (absolute) path, or <code>null</code> if
@@ -172,7 +172,7 @@
* unit or found by the <code>SearchEngine</code>.
*
* @param fullyQualifiedName the given fully qualified name
- * @exception JavaModelException if this element does not exist or if an
+ * @exception JavaModelException if this project does not exist or if an
* exception occurs while accessing its corresponding resource
* @return the first type found following this project's classpath
* with the given fully qualified name or <code>null</code> if none is found
@@ -197,7 +197,7 @@
*
* @param fullyQualifiedName the given fully qualified name
* @param owner the owner of the returned type's compilation unit
- * @exception JavaModelException if this element does not exist or if an
+ * @exception JavaModelException if this project does not exist or if an
* exception occurs while accessing its corresponding resource
* @return the first type found following this project's classpath
* with the given fully qualified name or <code>null</code> if none is found
@@ -222,7 +222,7 @@
*
* @param packageName the given package name
* @param typeQualifiedName the given type qualified name
- * @exception JavaModelException if this element does not exist or if an
+ * @exception JavaModelException if this project does not exist or if an
* exception occurs while accessing its corresponding resource
* @return the first type found following this project's classpath
* with the given package name and type qualified name
@@ -251,7 +251,7 @@
* @param packageName the given package name
* @param typeQualifiedName the given type qualified name
* @param owner the owner of the returned type's compilation unit
- * @exception JavaModelException if this element does not exist or if an
+ * @exception JavaModelException if this project does not exist or if an
* exception occurs while accessing its corresponding resource
* @return the first type found following this project's classpath
* with the given package name and type qualified name
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java
index 8040eeb..92c3bd4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java
@@ -175,7 +175,7 @@
* This is a handle-only method. The type parameter may or may not exist.
*
* @param name the given simple name
- * @return the type parameter declared in this methid with the given name
+ * @return the type parameter declared in this method with the given name
* @since 3.1
*/
ITypeParameter getTypeParameter(String name);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java
index 993f2cc..95d562e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java
@@ -300,7 +300,7 @@
* <p>
* Optionally, the new type can be positioned before the specified
* sibling. If no sibling is specified, the type will be appended
- * to this type.
+ * to this type.</p>
*
* <p>It is possible that a type with the same name already exists in this type.
* The value of the <code>force</code> parameter effects the resolution of
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
index 9e0e675..9ef3ef0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
@@ -19,12 +19,11 @@
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.compiler.*;
-import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.parser.Scanner;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.core.*;
-import org.eclipse.jdt.internal.core.JavaModelStatus;
import org.eclipse.jdt.internal.core.util.Messages;
/**
@@ -37,6 +36,7 @@
public final class JavaConventions {
private final static char DOT= '.';
+ private static final String PACKAGE_INFO = new String(TypeConstants.PACKAGE_INFO_NAME);
private final static Scanner SCANNER = new Scanner();
private JavaConventions() {
@@ -140,7 +140,7 @@
// JSR-175 metadata strongly recommends "package-info.java" as the
// file in which to store package annotations and
// the package-level spec (replaces package.html)
- if (!identifier.equals("package-info")) { //$NON-NLS-1$
+ if (!identifier.equals(PACKAGE_INFO)) {
IStatus status = validateIdentifier(identifier);
if (!status.isOK()) {
return status;
@@ -183,11 +183,16 @@
return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_notClassFileName, null);
}
identifier = name.substring(0, index);
- IStatus status = validateIdentifier(identifier);
- if (!status.isOK()) {
- return status;
+ // JSR-175 metadata strongly recommends "package-info.java" as the
+ // file in which to store package annotations and
+ // the package-level spec (replaces package.html)
+ if (!identifier.equals(PACKAGE_INFO)) {
+ IStatus status = validateIdentifier(identifier);
+ if (!status.isOK()) {
+ return status;
+ }
}
- status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
+ IStatus status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
if (!status.isOK()) {
return status;
}
@@ -305,7 +310,7 @@
}
return JavaModelStatus.VERIFIED_OK;
} else {
- return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_type_invalidName, (new String[] {name})), null);
+ return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_type_invalidName, name), null);
}
}
@@ -372,7 +377,7 @@
typeName = typeName.trim(); // grammar allows spaces
char[] scannedID = scannedIdentifier(typeName);
if (scannedID == null) {
- return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, (new String[] {typeName})), null);
+ return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, typeName), null);
}
IStatus status = workspace.validateName(new String(scannedID), IResource.FOLDER);
if (!status.isOK()) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index 4f1abbb..ca7ccd5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -64,15 +64,19 @@
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-import org.eclipse.core.runtime.preferences.IPreferencesService;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.core.search.TypeNameRequestor;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.builder.JavaBuilder;
+import org.eclipse.jdt.internal.core.builder.State;
import org.eclipse.jdt.internal.core.util.MementoTokenizer;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.Util;
import org.osgi.framework.BundleContext;
-import org.osgi.service.prefs.BackingStoreException;
/**
* The plug-in runtime class for the Java model plug-in containing the core
@@ -463,13 +467,13 @@
/**
* Possible configurable option ID.
* @see #getDefaultOptions()
- * @since 3.0
+ * @since 3.1
*/
public static final String COMPILER_PB_INVALID_JAVADOC_TAGS__DEPRECATED_REF = PLUGIN_ID + ".compiler.problem.invalidJavadocTagsDeprecatedRef"; //$NON-NLS-1$
/**
* Possible configurable option ID.
* @see #getDefaultOptions()
- * @since 3.0
+ * @since 3.1
*/
public static final String COMPILER_PB_INVALID_JAVADOC_TAGS__NOT_VISIBLE_REF = PLUGIN_ID + ".compiler.problem.invalidJavadocTagsNotVisibleRef"; //$NON-NLS-1$
/**
@@ -589,6 +593,18 @@
/**
* Possible configurable option ID.
* @see #getDefaultOptions()
+ * @since 3.1
+ */
+ public static final String COMPILER_PB_SUPPRESS_WARNINGS = PLUGIN_ID + ".compiler.problem.suppressWarnings"; //$NON-NLS-1$
+ /**
+ * Possible configurable option ID.
+ * @see #getDefaultOptions()
+ * @since 3.1
+ */
+ public static final String COMPILER_PB_UNHANDLED_WARNING_TOKEN = PLUGIN_ID + ".compiler.problem.unhandledWarningToken"; //$NON-NLS-1$
+ /**
+ * Possible configurable option ID.
+ * @see #getDefaultOptions()
*/
public static final String CORE_JAVA_BUILD_ORDER = PLUGIN_ID + ".computeJavaBuildOrder"; //$NON-NLS-1$
/**
@@ -816,13 +832,13 @@
* @see #getDefaultOptions()
* @since 3.1
*/
- public static final String CODEASSIST_FORBIDDEN_REFERENCE_CHECK = PLUGIN_ID + ".codeComplete.restrictionsCheck"; //$NON-NLS-1$
+ public static final String CODEASSIST_FORBIDDEN_REFERENCE_CHECK= PLUGIN_ID + ".codeComplete.forbiddenReferenceCheck"; //$NON-NLS-1$
/**
* Possible configurable option ID.
* @see #getDefaultOptions()
* @since 3.1
*/
- public static final String CODEASSIST_DISCOURAGED_REFERENCE_CHECK = PLUGIN_ID + ".codeComplete.discouragedReferenceCheck"; //$NON-NLS-1$
+ public static final String CODEASSIST_DISCOURAGED_REFERENCE_CHECK= PLUGIN_ID + ".codeComplete.discouragedReferenceCheck"; //$NON-NLS-1$
// *************** Possible values for configurable options. ********************
@@ -990,11 +1006,12 @@
* @since 3.0
*/
public static final String PRIVATE = "private"; //$NON-NLS-1$
-
- /*
- * Cache for options.
+ /**
+ * Possible configurable option value.
+ * @see #getDefaultOptions()
+ * @since 3.1
*/
- static Hashtable optionsCache;
+ public static final String NEVER = "never"; //$NON-NLS-1$
/**
* Creates the Java core plug-in.
@@ -1325,8 +1342,19 @@
* none was found.
* @since 2.1
*/
- public static ClasspathContainerInitializer getClasspathContainerInitializer(String containerID){
-
+ public static ClasspathContainerInitializer getClasspathContainerInitializer(String containerID) {
+ HashMap containerInitializersCache = JavaModelManager.getJavaModelManager().containerInitializersCache;
+ ClasspathContainerInitializer initializer = (ClasspathContainerInitializer) containerInitializersCache.get(containerID);
+ if (initializer == null) {
+ initializer = computeClasspathContainerInitializer(containerID);
+ if (initializer == null)
+ return null;
+ containerInitializersCache.put(containerID, initializer);
+ }
+ return initializer;
+ }
+
+ private static ClasspathContainerInitializer computeClasspathContainerInitializer(String containerID) {
Plugin jdtCorePlugin = JavaCore.getPlugin();
if (jdtCorePlugin == null) return null;
@@ -1854,7 +1882,7 @@
*
* COMPILER / Reporting Unchecked Type Operation
* When enabled, the compiler will issue an error or a warning whenever an operation involves generic types, and potentially
- * invalidates type safety since involving raw types (e.g. invoking #foo(X<String>) with arguments (X)).
+ * invalidates type safety since involving raw types (e.g. invoking #foo(X<String>) with arguments (X)).
* - option id: "org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation"
* - possible values: { "error", "warning", "ignore" }
* - default: "warning"
@@ -1988,7 +2016,7 @@
* Specify whether the compiler will verify overriding methods in order to report Javadoc missing tag problems.
* - option id: "org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding"
* - possible values: { "enabled", "disabled" }
- * - default: "enabled"
+ * - default: "disabled"
*
* COMPILER / Reporting Missing Javadoc Comments
* This is the generic control for the severity of missing Javadoc comment problems.
@@ -2010,7 +2038,7 @@
* Specify whether the compiler will verify overriding methods in order to report missing Javadoc comment problems.
* - option id: "org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding"
* - possible values: { "enabled", "disabled" }
- * - default: "enabled"
+ * - default: "disabled"
*
* COMPILER / Maximum number of problems reported per compilation unit
* Specify the maximum number of problems reported on each compilation unit.
@@ -2018,7 +2046,7 @@
* - possible values: "<n>" where <n> is zero or a positive integer (if zero then all problems are reported).
* - default: "100"
*
- * COMPILER / Define the Automatic Task Tags
+ * COMPILER / Defining the Automatic Task Tags
* When the tag list is not empty, the compiler will issue a task marker whenever it encounters
* one of the corresponding tag inside any comment in Java source code.
* Generated task messages will include the tag, and range until the next line separator or comment ending.
@@ -2027,11 +2055,12 @@
* will be detected for either tag "ToDo" or "#ToDo"). Respectively, a tag ending with a letter or digit cannot be followed
* by a letter or digit to be recognized ("ToDofoo" will not be recognized as a task for tag "ToDo", but "ToDo:foo" will
* be detected either for tag "ToDo" or "ToDo:").
+ * Note: the tasks are ordered, and the first matching tag will be selected; e.g. "TODO,TODO!" will match "TODO!" against "TODO" first.
* - option id: "org.eclipse.jdt.core.compiler.taskTags"
* - possible values: { "<tag>[,<tag>]*" } where <tag> is a String without any wild-card or leading/trailing spaces
* - default: "TODO,FIXME,XXX"
*
- * COMPILER / Define the Automatic Task Priorities
+ * COMPILER / Defining the Automatic Task Priorities
* In parallel with the Automatic Task Tags, this list defines the priorities (high, normal or low)
* of the task markers issued by the compiler.
* If the default is specified, the priority of each task marker is "NORMAL".
@@ -2039,7 +2068,7 @@
* - possible values: { "<priority>[,<priority>]*" } where <priority> is one of "HIGH", "NORMAL" or "LOW"
* - default: "NORMAL,HIGH,NORMAL"
*
- * COMPILER / Determine whether task tags are case-sensitive
+ * COMPILER / Determining whether task tags are case-sensitive
* When enabled, task tags are considered in a case-sensitive way.
* - option id: "org.eclipse.jdt.core.compiler.taskCaseSensitive"
* - possible values: { "enabled", "disabled" }
@@ -2059,6 +2088,20 @@
* - possible values: { "error", "warning", "ignore" }
* - default: "warning"
*
+ * COMPILER / Determining Effect of @SuppressWarnings
+ * When enabled, the @SuppressWarnings annotation can be used to suppress some compiler warnings.
+ * When disabled, all @SupressWarnings annotations are ignored; i.e., warnings are reported.
+ * - option id: "org.eclipse.jdt.core.compiler.problem.suppressWarnings"
+ * - possible values: { "enabled", "disabled" }
+ * - default: "enabled"
+ *
+ * COMPILER / Reporting Unhandled Warning Token for @SuppressWarnings
+ * When enabled, the compiler will issue an error or a warning when encountering a token
+ * it cannot handle inside a @SuppressWarnings annotation.
+ * - option id: "org.eclipse.jdt.core.compiler.problem.unhandledWarningToken"
+ * - possible values: { "error", "warning", "ignore" }
+ * - default: "warning"
+ *
* BUILDER / Specifying Filters for Resource Copying Control
* Allow to specify some filters to control the resource copy process.
* - option id: "org.eclipse.jdt.core.builder.resourceCopyExclusionFilter"
@@ -2272,19 +2315,18 @@
* - option id: "org.eclipse.jdt.core.codeComplete.argumentSuffixes"
* - possible values: { "<suffix>[,<suffix>]*" } where <suffix> is a String without any wild-card
* - default: ""
- *
+ *
* CODEASSIST / Activate Forbidden Reference Sensitive Completion
* When active, completion doesn't show that have forbidden reference.
- * - option id: "org.eclipse.jdt.core.codeComplete.restrictionsCheck"
+ * - option id: "org.eclipse.jdt.core.codeComplete.forbiddenReferenceCheck"
* - possible values: { "enabled", "disabled" }
- * - default: "disabled"
+ * - default: "enabled"
*
* CODEASSIST / Activate Discouraged Reference Sensitive Completion
* When active, completion doesn't show that have discouraged reference.
* - option id: "org.eclipse.jdt.core.codeComplete.discouragedReferenceCheck"
* - possible values: { "enabled", "disabled" }
* - default: "disabled"
- *
* </pre>
*
* @return a mutable table containing the default settings of all known options
@@ -2292,28 +2334,7 @@
* @see #setOptions(Hashtable)
*/
public static Hashtable getDefaultOptions(){
-
- Hashtable defaultOptions = new Hashtable(10);
-
- // see JavaCorePreferenceInitializer#initializeDefaultPluginPreferences() for changing default settings
- JavaModelManager manager = JavaModelManager.getJavaModelManager();
- IEclipsePreferences defaultPreferences = manager.getDefaultPreferences();
- HashSet optionNames = manager.optionNames;
-
- // initialize preferences to their default
- Iterator iterator = optionNames.iterator();
- while (iterator.hasNext()) {
- String propertyName = (String) iterator.next();
- String value = defaultPreferences.get(propertyName, null);
- if (value != null) defaultOptions.put(propertyName, value);
- }
- // get encoding through resource plugin
- defaultOptions.put(CORE_ENCODING, getEncoding());
- // backward compatibility
- defaultOptions.put(COMPILER_PB_INVALID_IMPORT, ERROR);
- defaultOptions.put(COMPILER_PB_UNREACHABLE_CODE, ERROR);
-
- return defaultOptions;
+ return JavaModelManager.getJavaModelManager().getDefaultOptions();
}
/**
@@ -2361,23 +2382,7 @@
* @since 2.0
*/
public static String getOption(String optionName) {
-
- if (CORE_ENCODING.equals(optionName)){
- return getEncoding();
- }
- // backward compatibility
- if (COMPILER_PB_INVALID_IMPORT.equals(optionName)
- || COMPILER_PB_UNREACHABLE_CODE.equals(optionName)) {
- return ERROR;
- }
- String propertyName = optionName;
- JavaModelManager manager = JavaModelManager.getJavaModelManager();
- if (manager.optionNames.contains(propertyName)){
- IPreferencesService service = Platform.getPreferencesService();
- String value = service.get(optionName, null, manager.preferencesLookup);
- return value==null ? null : value.trim();
- }
- return null;
+ return JavaModelManager.getJavaModelManager().getOption(optionName);
}
/**
@@ -2393,41 +2398,9 @@
* @see JavaCorePreferenceInitializer for changing default settings
*/
public static Hashtable getOptions() {
-
- // return cached options if already computed
- if (optionsCache != null) return new Hashtable(optionsCache);
-
- // init
- Hashtable options = new Hashtable(10);
- JavaModelManager manager = JavaModelManager.getJavaModelManager();
- HashSet optionNames = manager.optionNames;
- IPreferencesService service = Platform.getPreferencesService();
-
- // set options using preferences service lookup
- Iterator iterator = optionNames.iterator();
- while (iterator.hasNext()) {
- String propertyName = (String) iterator.next();
- String propertyValue = service.get(propertyName, null, manager.preferencesLookup);
- if (propertyValue != null) {
- options.put(propertyName, propertyValue);
- }
- }
-
- // get encoding through resource plugin
- options.put(CORE_ENCODING, getEncoding());
-
- // backward compatibility
- options.put(COMPILER_PB_INVALID_IMPORT, ERROR);
- options.put(COMPILER_PB_UNREACHABLE_CODE, ERROR);
-
- // store built map in cache
- optionsCache = new Hashtable(options);
-
- // return built map
- return options;
+ return JavaModelManager.getJavaModelManager().getOptions();
}
-
/**
* Returns the single instance of the Java core plug-in runtime class.
*
@@ -2514,8 +2487,8 @@
}
// outside the workspace
if (target instanceof File) {
- File externalFile = (File) target;
- if (externalFile.isFile()) {
+ File externalFile = JavaModel.getFile(target);
+ if (externalFile != null) {
String fileName = externalFile.getName().toLowerCase();
if (fileName.endsWith(SuffixConstants.SUFFIX_STRING_jar) || fileName.endsWith(SuffixConstants.SUFFIX_STRING_zip)) {
// external binary archive
@@ -2618,6 +2591,139 @@
}
/**
+ * Initializes JavaCore internal structures to allow subsequent operations (such
+ * as the ones that need a resolved classpath) to run full speed. A client may
+ * choose to call this method in a background thread early after the workspace
+ * has started so that the initialization is transparent to the user.
+ * <p>
+ * However calling this method is optional. Services will lazily perform
+ * initialization when invoked. This is only a way to reduce initialization
+ * overhead on user actions, if it can be performed before at some
+ * appropriate moment.
+ * </p><p>
+ * This initialization runs accross all Java projects in the workspace. Thus the
+ * workspace root scheduling rule is used during this operation.
+ * </p><p>
+ * This method may return before the initialization is complete. The
+ * initialization will then continue in a background thread.
+ * </p><p>
+ * This method can be called concurrently.
+ * </p>
+ *
+ * @param monitor a progress monitor, or <code>null</code> if progress
+ * reporting and cancellation are not desired
+ * @exception CoreException if the initialization fails,
+ * the status of the exception indicates the reason of the failure
+ * @since 3.1
+ */
+ public static void initializeAfterLoad(IProgressMonitor monitor) throws CoreException {
+ Job job = new Job(Messages.javamodel_initialization) {
+ protected IStatus run(IProgressMonitor progressMonitor) {
+ // dummy query for waiting until the indexes are ready and classpath containers/variables are initialized
+ SearchEngine engine = new SearchEngine();
+ IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); // initialize all containers and variables
+ try {
+ engine.searchAllTypeNames(
+ null,
+ "!@$#!@".toCharArray(), //$NON-NLS-1$
+ SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE,
+ IJavaSearchConstants.CLASS,
+ scope,
+ new TypeNameRequestor() {
+ public void acceptType(
+ int modifiers,
+ char[] packageName,
+ char[] simpleTypeName,
+ char[][] enclosingTypeNames,
+ String path) {
+ // no type to accept
+ }
+ },
+ // will not activate index query caches if indexes are not ready, since it would take to long
+ // to wait until indexes are fully rebuild
+ IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH,
+ progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 99) // 99% of the time is spent in the dummy search
+ );
+ } catch (JavaModelException e) {
+ // /search failed: ignore
+ } catch (OperationCanceledException e) {
+ if (progressMonitor != null && progressMonitor.isCanceled())
+ throw e;
+ // else indexes were not ready: catch the exception so that jars are still refreshed
+ }
+
+ // check if the build state version number has changed since last session
+ // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=98969)
+ QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "stateVersionNumber"); //$NON-NLS-1$
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ String versionNumber = null;
+ try {
+ versionNumber = root.getPersistentProperty(qName);
+ } catch (CoreException e) {
+ // could not read version number: consider it is new
+ }
+ final JavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
+ String newVersionNumber = Byte.toString(State.VERSION);
+ if (!newVersionNumber.equals(versionNumber)) {
+ // build state version number has changed: touch every projects to force a rebuild
+ if (JavaBuilder.DEBUG)
+ System.out.println("Build state version number has changed"); //$NON-NLS-1$
+ IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor progressMonitor2) throws CoreException {
+ IJavaProject[] projects = null;
+ try {
+ projects = model.getJavaProjects();
+ } catch (JavaModelException e) {
+ // could not get Java projects: ignore
+ }
+ if (projects != null) {
+ for (int i = 0, length = projects.length; i < length; i++) {
+ IJavaProject project = projects[i];
+ try {
+ if (JavaBuilder.DEBUG)
+ System.out.println("Touching " + project.getElementName()); //$NON-NLS-1$
+ project.getProject().touch(progressMonitor2);
+ } catch (CoreException e) {
+ // could not touch this project: ignore
+ }
+ }
+ }
+ }
+ };
+ try {
+ ResourcesPlugin.getWorkspace().run(runnable, progressMonitor);
+ } catch (CoreException e) {
+ // could not touch all projects
+ }
+ try {
+ root.setPersistentProperty(qName, newVersionNumber);
+ } catch (CoreException e) {
+ Util.log(e, "Could not persist build state version number"); //$NON-NLS-1$
+ }
+ }
+
+ // ensure external jars are refreshed (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=93668)
+ try {
+ model.refreshExternalArchives(
+ null/*refresh all projects*/,
+ progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 1) // 1% of the time is spent in jar refresh
+ );
+ } catch (JavaModelException e) {
+ // refreshing failed: ignore
+ }
+
+ return Status.OK_STATUS;
+ }
+ public boolean belongsTo(Object family) {
+ return PLUGIN_ID.equals(family);
+ }
+ };
+ job.setPriority(Job.SHORT);
+ job.schedule(2000); // wait for the startup activity to calm down
+
+ }
+
+ /**
* Returns whether the given marker references the given Java element.
* Used for markers, which denote a Java element rather than a resource.
*
@@ -2812,7 +2918,8 @@
* </p>
* <p>
* The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
- * this entry. If no extra attributes are provided, an empty array must be passed in.
+ * this entry. If no extra attributes are provided, an empty array must be passed in.<br>
+ * Note that this list should not contain any duplicate name.
* </p>
* <p>
* The <code>isExported</code> flag indicates whether this entry is contributed to dependent
@@ -2992,7 +3099,8 @@
* </p>
* <p>
* The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
- * this entry. If no extra attributes are provided, an empty array must be passed in.
+ * this entry. If no extra attributes are provided, an empty array must be passed in.<br>
+ * Note that this list should not contain any duplicate name.
* </p>
* <p>
* The <code>isExported</code> flag indicates whether this entry is contributed to dependent
@@ -3116,7 +3224,8 @@
* </p>
* <p>
* The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
- * this entry. If no extra attributes are provided, an empty array must be passed in.
+ * this entry. If no extra attributes are provided, an empty array must be passed in.<br>
+ * Note that this list should not contain any duplicate name.
* </p>
* <p>
* The <code>isExported</code> flag indicates whether this entry is contributed to dependent
@@ -3325,7 +3434,8 @@
* </p>
* <p>
* The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
- * this entry. If no extra attributes are provided, an empty array must be passed in.
+ * this entry. If no extra attributes are provided, an empty array must be passed in.<br>
+ * Note that this list should not contain any duplicate name.
* </p>
*
* @param path the absolute workspace-relative path of a source folder
@@ -3449,7 +3559,8 @@
* </p>
* <p>
* The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
- * this entry. If no extra attributes are provided, an empty array must be passed in.
+ * this entry. If no extra attributes are provided, an empty array must be passed in.<br>
+ * Note that this list should not contain any duplicate name.
* </p>
* <p>
* The <code>isExported</code> flag indicates whether this entry is contributed to dependent
@@ -3973,38 +4084,7 @@
* @see JavaCorePreferenceInitializer for changing default settings
*/
public static void setOptions(Hashtable newOptions) {
-
- try {
- JavaModelManager manager = JavaModelManager.getJavaModelManager();
- IEclipsePreferences defaultPreferences = manager.getDefaultPreferences();
- IEclipsePreferences instancePreferences = manager.getInstancePreferences();
-
- if (newOptions == null){
- instancePreferences.clear();
- } else {
- Enumeration keys = newOptions.keys();
- while (keys.hasMoreElements()){
- String key = (String)keys.nextElement();
- if (!JavaModelManager.getJavaModelManager().optionNames.contains(key)) continue; // unrecognized option
- if (key.equals(CORE_ENCODING)) continue; // skipped, contributed by resource prefs
- String value = (String)newOptions.get(key);
- String defaultValue = defaultPreferences.get(key, null);
- if (defaultValue != null && defaultValue.equals(value)) {
- instancePreferences.remove(key);
- } else {
- instancePreferences.put(key, value);
- }
- }
- }
-
- // persist options
- instancePreferences.flush();
-
- // update cache
- optionsCache = newOptions==null ? null : new Hashtable(newOptions);
- } catch (BackingStoreException e) {
- // ignore
- }
+ JavaModelManager.getJavaModelManager().setOptions(newOptions);
}
/* (non-Javadoc)
@@ -4016,11 +4096,6 @@
*/
public void stop(BundleContext context) throws Exception {
try {
- savePluginPreferences();
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- workspace.removeResourceChangeListener(JavaModelManager.getJavaModelManager().deltaState);
- workspace.removeSaveParticipant(this);
-
JavaModelManager.getJavaModelManager().shutdown();
} finally {
// ensure we call super.stop as the last thing
@@ -4028,15 +4103,6 @@
}
}
- /**
- * Initiate the background indexing process.
- * This should be deferred after the plugin activation.
- */
- private void startIndexing() {
-
- JavaModelManager.getJavaModelManager().getIndexManager().reset();
- }
-
/* (non-Javadoc)
* Startup the JavaCore plug-in.
* <p>
@@ -4048,71 +4114,6 @@
*/
public void start(BundleContext context) throws Exception {
super.start(context);
-
- final JavaModelManager manager = JavaModelManager.getJavaModelManager();
- try {
- manager.configurePluginDebugOptions();
-
- // request state folder creation (workaround 19885)
- JavaCore.getPlugin().getStateLocation();
-
- // Initialize eclipse preferences
- manager.initializePreferences();
-
- // Listen to preference changes
- Preferences.IPropertyChangeListener propertyListener = new Preferences.IPropertyChangeListener() {
- public void propertyChange(Preferences.PropertyChangeEvent event) {
- JavaCore.optionsCache = null;
- }
- };
- JavaCore.getPlugin().getPluginPreferences().addPropertyChangeListener(propertyListener);
-
- // retrieve variable values
- manager.loadVariablesAndContainers();
-
- final IWorkspace workspace = ResourcesPlugin.getWorkspace();
- workspace.addResourceChangeListener(
- manager.deltaState,
- IResourceChangeEvent.PRE_BUILD
- | IResourceChangeEvent.POST_BUILD
- | IResourceChangeEvent.POST_CHANGE
- | IResourceChangeEvent.PRE_DELETE
- | IResourceChangeEvent.PRE_CLOSE);
-
- startIndexing();
-
- // process deltas since last activated in indexer thread so that indexes are up-to-date.
- // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658
- Job processSavedState = new Job(Messages.savedState_jobName) {
- protected IStatus run(IProgressMonitor monitor) {
- try {
- // add save participant and process delta atomically
- // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59937
- workspace.run(
- new IWorkspaceRunnable() {
- public void run(IProgressMonitor progress) throws CoreException {
- ISavedState savedState = workspace.addSaveParticipant(JavaCore.this, manager);
- if (savedState != null) {
- // the event type coming from the saved state is always POST_AUTO_BUILD
- // force it to be POST_CHANGE so that the delta processor can handle it
- manager.deltaState.getDeltaProcessor().overridenEventType = IResourceChangeEvent.POST_CHANGE;
- savedState.processResourceChangeEvents(manager.deltaState);
- }
- }
- },
- monitor);
- } catch (CoreException e) {
- return e.getStatus();
- }
- return Status.OK_STATUS;
- }
- };
- processSavedState.setSystem(true);
- processSavedState.setPriority(Job.SHORT); // process asap
- processSavedState.schedule();
- } catch (RuntimeException e) {
- manager.shutdown();
- throw e;
- }
+ JavaModelManager.getJavaModelManager().startup();
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
index b8c6ea9..b2fac6f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
@@ -1005,8 +1005,8 @@
* @param typeSignature the type signature string
* @return the kind of type signature; one of the kind constants:
* {@link #ARRAY_TYPE_SIGNATURE}, {@link #CLASS_TYPE_SIGNATURE},
- * {@link #BASE_TYPE_SIGNATURE}, {@link #TYPE_VARIABLE_SIGNATURE}
- * or {@link #WILDCARD_TYPE_SIGNATURE}
+ * {@link #BASE_TYPE_SIGNATURE}, or {@link #TYPE_VARIABLE_SIGNATURE},
+ * or (since 3.1) {@link #WILDCARD_TYPE_SIGNATURE} or {@link #CAPTURE_TYPE_SIGNATURE}
* @exception IllegalArgumentException if this is not a type signature
* @since 3.0
*/
@@ -1016,6 +1016,24 @@
throw new IllegalArgumentException();
}
char c = typeSignature[0];
+ if (c == C_GENERIC_START) {
+ int count = 1;
+ for (int i = 1, length = typeSignature.length; i < length; i++) {
+ switch (typeSignature[i]) {
+ case C_GENERIC_START:
+ count++;
+ break;
+ case C_GENERIC_END:
+ count--;
+ break;
+ }
+ if (count == 0) {
+ if (i+1 < length)
+ c = typeSignature[i+1];
+ break;
+ }
+ }
+ }
switch (c) {
case C_ARRAY :
return ARRAY_TYPE_SIGNATURE;
@@ -1051,7 +1069,8 @@
* @param typeSignature the type signature string
* @return the kind of type signature; one of the kind constants:
* {@link #ARRAY_TYPE_SIGNATURE}, {@link #CLASS_TYPE_SIGNATURE},
- * {@link #BASE_TYPE_SIGNATURE}, or {@link #TYPE_VARIABLE_SIGNATURE}
+ * {@link #BASE_TYPE_SIGNATURE}, or {@link #TYPE_VARIABLE_SIGNATURE},
+ * or (since 3.1) {@link #WILDCARD_TYPE_SIGNATURE} or {@link #CAPTURE_TYPE_SIGNATURE}
* @exception IllegalArgumentException if this is not a type signature
* @since 3.0
*/
@@ -1061,6 +1080,24 @@
throw new IllegalArgumentException();
}
char c = typeSignature.charAt(0);
+ if (c == C_GENERIC_START) {
+ int count = 1;
+ for (int i = 1, length = typeSignature.length(); i < length; i++) {
+ switch (typeSignature.charAt(i)) {
+ case C_GENERIC_START:
+ count++;
+ break;
+ case C_GENERIC_END:
+ count--;
+ break;
+ }
+ if (count == 0) {
+ if (i+1 < length)
+ c = typeSignature.charAt(i+1);
+ break;
+ }
+ }
+ }
switch (c) {
case C_ARRAY :
return ARRAY_TYPE_SIGNATURE;
@@ -1084,7 +1121,7 @@
case C_EXTENDS :
return WILDCARD_TYPE_SIGNATURE;
case C_CAPTURE :
- return CAPTURE_TYPE_SIGNATURE;
+ return CAPTURE_TYPE_SIGNATURE;
default :
throw new IllegalArgumentException();
}
@@ -1166,6 +1203,8 @@
* @return the list of thrown exception type signatures
* @exception IllegalArgumentException if the signature is syntactically
* incorrect
+ *
+ * @since 3.1
*/
public static String[] getThrownExceptionTypes(String methodSignature) throws IllegalArgumentException {
char[][] parameterTypes = getThrownExceptionTypes(methodSignature.toCharArray());
@@ -1180,6 +1219,8 @@
* @return the list of thrown exception type signatures
* @exception IllegalArgumentException if the signature is syntactically
* incorrect
+ *
+ * @since 3.1
*/
public static char[][] getThrownExceptionTypes(char[] methodSignature) throws IllegalArgumentException {
// skip type parameters
@@ -1365,15 +1406,43 @@
return result;
}
i = CharOperation.indexOf(C_COLON, methodOrTypeSignature, i);
- if (i < 0 || i >= length) throw new IllegalArgumentException();
+ if (i < 0 || i >= length)
+ throw new IllegalArgumentException();
// iterate over bounds
nextBound: while (methodOrTypeSignature[i] == ':') {
i++; // skip colon
- if (methodOrTypeSignature[i] == ':') {
- continue nextBound; // empty bound
+ switch (methodOrTypeSignature[i]) {
+ case ':':
+ // no class bound
+ break;
+ case C_GENERIC_END:
+ break;
+ case C_RESOLVED:
+ try {
+ i = Util.scanClassTypeSignature(methodOrTypeSignature, i);
+ i++; // position at start of next param if any
+ } catch (IllegalArgumentException e) {
+ // not a class type signature -> it is a new type parameter
+ }
+ break;
+ case C_ARRAY:
+ try {
+ i = Util.scanArrayTypeSignature(methodOrTypeSignature, i);
+ i++; // position at start of next param if any
+ } catch (IllegalArgumentException e) {
+ // not an array type signature -> it is a new type parameter
+ }
+ break;
+ case C_TYPE_VARIABLE:
+ try {
+ i = Util.scanTypeVariableSignature(methodOrTypeSignature, i);
+ i++; // position at start of next param if any
+ } catch (IllegalArgumentException e) {
+ // not a type variable signature -> it is a new type parameter
+ }
+ break;
+ // default: another type parameter is starting
}
- i = Util.scanTypeSignature(methodOrTypeSignature, i);
- i++; // position at start of next param if any
}
paramList.add(CharOperation.subarray(methodOrTypeSignature, paramStart, i));
paramStart = i; // next param start from here
@@ -1980,74 +2049,77 @@
return CharOperation.toStrings(getSimpleNames(name.toCharArray()));
}
-
/**
- * Returns a method signature with any capture information removed.
- * Returns the method signature itself if no capture information is
+ * Removes any capture information from the given type or method signature
+ * and returns the resulting signature.
+ * Returns the type or method signature itself if no capture information is
* present.
* <p>
* For example (using equivalent string-based method):
* <pre>
* <code>
- * removeCaptureFromMethod("LTest<!+Ljava.lang.Throwable;>;")
+ * removeCapture("LTest<!+Ljava.lang.Throwable;>;")
* will return: "LTest<+Ljava.lang.Throwable;>;"
* </code>
* </pre>
* </p>
*
- * @param captureSignature the signature which may have been captured
- * @return new signature without capture information or siganture itself
- * if no specific capture information was there
- * @exception NullPointerException if <code>captureSignature</code> is null
+ * @param methodOrTypeSignature the signature which may have been captured
+ * @return a new signature without capture information or the signature itself
+ * if no specific capture information is present
+ * @exception NullPointerException if <code>methodOrTypeSignature</code> is null
+ *
* @since 3.1
- * TODO (frederic) Create remove(char[], char) method on CharOperation and call it from here
*/
-public static char[] removeCaptureFromMethod(char[] captureSignature) {
+public static char[] removeCapture(char[] methodOrTypeSignature) {
+// TODO (frederic) Create remove(char[], char) method on CharOperation and call it from here
char[] result = null;
int count = 0;
- for (int i = 0, length = captureSignature.length; i < length; i++) {
- char c = captureSignature[i];
+ for (int i = 0, length = methodOrTypeSignature.length; i < length; i++) {
+ char c = methodOrTypeSignature[i];
if (c == C_CAPTURE) {
if (result == null) {
result = new char[length];
- System.arraycopy(captureSignature, 0, result, 0, i);
+ System.arraycopy(methodOrTypeSignature, 0, result, 0, i);
count = i;
}
} else if (result != null) {
result[count++] = c;
}
}
- if (result == null) return captureSignature;
+ if (result == null) return methodOrTypeSignature;
System.arraycopy(result, 0, result = new char[count], 0, count);
return result;
}
/**
- * Returns a method signature with any capture information removed.
- * Returns the method signature itself if no capture information is
+ * Removes any capture information from the given type or method signature
+ * and returns the resulting signature.
+ * Returns the type or method signature itself if no capture information is
* present.
* <p>
* For example:
* <pre>
* <code>
- * removeCaptureFromMethod("LTest<!+Ljava.lang.Throwable;>;")
+ * removeCapture("LTest<!+Ljava.lang.Throwable;>;")
* will return: "LTest<+Ljava.lang.Throwable;>;"
* </code>
* </pre>
* </p>
*
- * @param captureSignature the signature which may have been captured
- * @return new signature without capture information or siganture itself
- * if no specific capture information was there
- * @exception NullPointerException if <code>captureSignature</code> is null
+ * @param methodOrTypeSignature the signature which may have been captured
+ * @return a new signature without capture information or the signature itself
+ * if no specific capture information is present
+ * @exception NullPointerException if <code>methodOrTypeSignature</code> is null
+ *
* @since 3.1
*/
-public static String removeCaptureFromMethod(String captureSignature) {
- char[] array = captureSignature.toCharArray();
- char[] result = removeCaptureFromMethod(array);
- if (array == result) return captureSignature;
- return new String(result);
+public static String removeCapture(String methodOrTypeSignature) {
+ char[] array = methodOrTypeSignature.toCharArray();
+ char[] result = removeCapture(array);
+ if (array == result) return methodOrTypeSignature;
+ return new String(result);
}
/**
@@ -2362,15 +2434,32 @@
* @see Util#scanArrayTypeSignature(char[], int)
*/
private static int appendArrayTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer, boolean isVarArgs) {
+ int length = string.length;
// need a minimum 2 char
- if (start >= string.length - 1) {
+ if (start >= length - 1) {
throw new IllegalArgumentException();
}
char c = string[start];
if (c != C_ARRAY) { //$NON-NLS-1$
throw new IllegalArgumentException();
}
- int e = appendTypeSignature(string, start + 1, fullyQualifyTypeNames, buffer);
+
+ int index = start;
+ c = string[++index];
+ while(c == C_ARRAY) {
+ // need a minimum 2 char
+ if (index >= length - 1) {
+ throw new IllegalArgumentException();
+ }
+ c = string[++index];
+ }
+
+ int e = appendTypeSignature(string, index, fullyQualifyTypeNames, buffer);
+
+ for(int i = 1, dims = index - start; i < dims; i++) {
+ buffer.append('[').append(']');
+ }
+
if (isVarArgs) {
buffer.append('.').append('.').append('.');
} else {
@@ -2674,6 +2763,8 @@
* variable argument, <code>false</code> otherwise
* @see #toCharArray(char[], char[], char[][], boolean, boolean)
* @return the string representation of the method signature
+ *
+ * @since 3.1
*/
public static String toString(String methodSignature, String methodName, String[] parameterNames, boolean fullyQualifyTypeNames, boolean includeReturnType, boolean isVarArgs) {
char[][] params;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
index 899f8ac..0416797 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
@@ -375,7 +375,8 @@
* the Unicode 4.0 is supporte, otherwise Unicode 3.0 is supported.
* @return a scanner
* @see org.eclipse.jdt.core.compiler.IScanner
- * @since 3.0
+ *
+ * @since 3.1
*/
public static IScanner createScanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean recordLineSeparator, String sourceLevel, String complianceLevel) {
PublicScanner scanner = null;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java
index 3d1f839..fe44004 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java
@@ -202,7 +202,7 @@
* <li>The position specified is less than -1 or is greater than the snippet's
* length (INDEX_OUT_OF_BOUNDS)</li>
* </ul>
- * @since 3.0
+ * @since 3.1
*/
public void codeComplete(
String codeSnippet,
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java
index 0840191..c0737f6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.jdt.core.jdom;
-import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.jdt.internal.core.jdom.*;
/**
@@ -24,11 +23,13 @@
* org.eclipse.jdt.core.dom package.
*/
public class DOMFactory implements IDOMFactory {
+ String lineSeparator;
/**
* Creates a new DOM factory.
*/
public DOMFactory() {
// constructor is explicitly API
+ this.lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(null, null/*take the workspace line separator as no project is available*/);
}
/* (non-Javadoc)
* Method declared on IDOMFactory.
@@ -58,7 +59,7 @@
* Method declared on IDOMFactory.
*/
public IDOMField createField() {
- return createField("Object aField;"+ Util.LINE_SEPARATOR); //$NON-NLS-1$
+ return createField("Object aField;"+ this.lineSeparator); //$NON-NLS-1$
}
/* (non-Javadoc)
* Method declared on IDOMFactory.
@@ -88,7 +89,7 @@
* Method declared on IDOMFactory.
*/
public IDOMInitializer createInitializer() {
- return createInitializer("static {}"+ Util.LINE_SEPARATOR); //$NON-NLS-1$
+ return createInitializer("static {}"+ this.lineSeparator); //$NON-NLS-1$
}
/* (non-Javadoc)
* Method declared on IDOMFactory.
@@ -103,7 +104,7 @@
* Method declared on IDOMFactory.
*/
public IDOMMethod createMethod() {
- return createMethod("public void newMethod() {"+ Util.LINE_SEPARATOR+"}"+ Util.LINE_SEPARATOR); //$NON-NLS-2$ //$NON-NLS-1$
+ return createMethod("public void newMethod() {"+ this.lineSeparator+"}"+ this.lineSeparator); //$NON-NLS-2$ //$NON-NLS-1$
}
/* (non-Javadoc)
* Method declared on IDOMFactory.
@@ -133,19 +134,19 @@
* Method declared on IDOMFactory.
*/
public IDOMType createType() {
- return createType("public class AClass {"+ Util.LINE_SEPARATOR +"}"+ Util.LINE_SEPARATOR); //$NON-NLS-2$ //$NON-NLS-1$
+ return createType("public class AClass {"+ this.lineSeparator +"}"+ this.lineSeparator); //$NON-NLS-2$ //$NON-NLS-1$
}
/* (non-Javadoc)
* Method declared on IDOMFactory.
*/
public IDOMType createClass() {
- return createType("public class AClass {"+ Util.LINE_SEPARATOR +"}"+ Util.LINE_SEPARATOR); //$NON-NLS-2$ //$NON-NLS-1$
+ return createType("public class AClass {"+ this.lineSeparator +"}"+ this.lineSeparator); //$NON-NLS-2$ //$NON-NLS-1$
}
/* (non-Javadoc)
* Method declared on IDOMFactory.
*/
public IDOMType createInterface() {
- return createType("public interface AnInterface {"+ Util.LINE_SEPARATOR +"}"+ Util.LINE_SEPARATOR); //$NON-NLS-2$ //$NON-NLS-1$
+ return createType("public interface AnInterface {"+ this.lineSeparator +"}"+ this.lineSeparator); //$NON-NLS-2$ //$NON-NLS-1$
}
/* (non-Javadoc)
* Method declared on IDOMFactory.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java
index 015b526..913009a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java
@@ -50,12 +50,7 @@
/**
* Sets the modifier flags for this import. The flags can be examined using class
* <code>Flags</code>. Only the static flag is meaningful for import declarations.
- * <p>
- * Note: Static imports are an experimental language feature
- * under discussion in JSR-201 and under consideration for inclusion
- * in the 1.5 release of J2SE. The support here is therefore tentative
- * and subject to change.
- * </p>
+ *
* @param flags the modifier flags for this import
* @see org.eclipse.jdt.core.Flags
* @since 3.0
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java
index bbbfc65..2bba98d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java
@@ -16,6 +16,7 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.internal.core.SortElementsOperation;
/**
@@ -65,7 +66,8 @@
public static final String RELATIVE_ORDER = "relativeOrder"; //$NON-NLS-1$
/**
- * Reorders the declarations in the given compilation unit. The caller is
+ * Reorders the declarations in the given compilation unit according to
+ * JLS2 rules. The caller is
* responsible for arranging in advance that the given compilation unit is
* a working copy, and for saving the changes afterwards.
* <p>
@@ -87,7 +89,7 @@
* </p>
* <p>
* The <code>compare</code> method of the given comparator is passed pairs
- * of AST body declarations (subclasses of <code>BodyDeclaration</code>)
+ * of JLS2 AST body declarations (subclasses of <code>BodyDeclaration</code>)
* representing body declarations at the same level. The comparator is
* called on body declarations of nested classes, including anonymous and
* local classes, but always at the same level. Clients need to provide
@@ -143,7 +145,8 @@
* corresponding source positions in the permuted source code string
* (but not necessarily any longer in non-decreasing order).
* @param comparator the comparator capable of ordering
- * <code>BodyDeclaration</code>s
+ * <code>BodyDeclaration</code>s; this comparator is passed AST nodes
+ * from a JLS2 AST
* @param options bitwise-or of option flags; <code>0</code> for default
* behavior (reserved for future growth)
* @param monitor the progress monitor to notify, or <code>null</code> if
@@ -160,17 +163,162 @@
* or if the given comparator is null.
* @see org.eclipse.jdt.core.dom.BodyDeclaration
* @see #RELATIVE_ORDER
+ * @deprecated Clients should port their code to use the new JLS3 AST API and call
+ * {@link #sort(int, ICompilationUnit, int[], Comparator, int, IProgressMonitor)
+ * CompilationUnitSorter.sort(AST.JLS3, compilationUnit, positions, comparator, options, monitor)}
+ * instead of using this method.
*/
public static void sort(ICompilationUnit compilationUnit,
int[] positions,
Comparator comparator,
int options,
IProgressMonitor monitor) throws JavaModelException {
- if (compilationUnit == null || comparator == null) {
- throw new IllegalArgumentException();
- }
- ICompilationUnit[] compilationUnits = new ICompilationUnit[] { compilationUnit };
- SortElementsOperation operation = new SortElementsOperation(compilationUnits, positions, comparator);
- operation.runOperation(monitor);
+ sort(AST.JLS2, compilationUnit, positions, comparator, options, monitor);
}
+
+ /**
+ * Reorders the declarations in the given compilation unit according to
+ * the specified AST level. The caller is responsible for arranging in
+ * advance that the given compilation unit is a working copy, and for
+ * saving the changes afterwards.
+ * <p>
+ * <b>Note:</b> Reordering the members within a type declaration might be
+ * more than a cosmetic change and could have potentially serious
+ * repercussions. Firstly, the order in which the fields of a type are
+ * initialized is significant in the Java language; reordering fields
+ * and initializers may result in compilation errors or change the execution
+ * behavior of the code. Secondly, reordering a class's members may affect
+ * how its instances are serialized. This operation should therefore be used
+ * with caution and due concern for potential negative side effects.
+ * </p>
+ * <p>
+ * The optional <code>positions</code> array contains a non-decreasing
+ * ordered list of character-based source positions within the compilation
+ * unit's source code string. Upon return from this method, the positions in
+ * the array reflect the corresponding new locations in the modified source
+ * code string. Note that this operation modifies the given array in place.
+ * </p>
+ * <p>
+ * The <code>compare</code> method of the given comparator is passed pairs
+ * of body declarations (subclasses of <code>BodyDeclaration</code>)
+ * representing body declarations at the same level. The nodes are from an
+ * AST of the specified level
+ * ({@link org.eclipse.jdt.core.dom.ASTParser#newParser(int)}. Clients
+ * will generally specify AST.JLS3 since that will cover all constructs found
+ * in Java 1.0, 1.1, 1.2, 1.3, 1.4, and 1.5 source code.
+ * The comparator is called on body declarations of nested classes, including
+ * anonymous and local classes, but always at the same level. Clients need to provide
+ * a comparator implementation (there is no standard comparator). The
+ * <code>RELATIVE_ORDER</code> property attached to these AST nodes afforts
+ * the comparator a way to preserve the original relative order.
+ * </p>
+ * <p>
+ * The body declarations passed as parameters to the comparator
+ * always carry at least the following minimal signature information:
+ * <br>
+ * <table border="1" width="80%" cellpadding="5">
+ * <tr>
+ * <td width="20%"><code>TypeDeclaration</code></td>
+ * <td width="50%"><code>modifiers, isInterface, name, superclass,
+ * superInterfaces, typeParameters<br>
+ * RELATIVE_ORDER property</code></td>
+ * </tr>
+ * <tr>
+ * <td width="20%"><code>FieldDeclaration</code></td>
+ * <td width="50%"><code>modifiers, type, fragments
+ * (VariableDeclarationFragments
+ * with name only)<br>
+ * RELATIVE_ORDER property</code></td>
+ * </tr>
+ * <tr>
+ * <td width="20%"><code>MethodDeclaration</code></td>
+ * <td width="50%"><code>modifiers, isConstructor, returnType, name,
+ * typeParameters, parameters
+ * (SingleVariableDeclarations with name, type, and modifiers only),
+ * thrownExceptions<br>
+ * RELATIVE_ORDER property</code></td>
+ * </tr>
+ * <tr>
+ * <td width="20%"><code>Initializer</code></td>
+ * <td width="50%"><code>modifiers<br>
+ * RELATIVE_ORDER property</code></td>
+ * </tr>
+ * <tr>
+ * <td width="20%"><code>AnnotationTypeDeclaration</code></td>
+ * <td width="50%"><code>modifiers, name<br>
+ * RELATIVE_ORDER property</code></td>
+ * </tr>
+ * <tr>
+ * <td width="20%"><code>AnnotationTypeMemberDeclaration</code></td>
+ * <td width="50%"><code>modifiers, name, type, default<br>
+ * RELATIVE_ORDER property</code></td>
+ * </tr>
+ * <tr>
+ * <td width="20%"><code>EnumDeclaration</code></td>
+ * <td width="50%"><code>modifiers, name, superInterfaces<br>
+ * RELATIVE_ORDER property</code></td>
+ * </tr>
+ * <tr>
+ * <td width="20%"><code>EnumConstantDeclaration</code></td>
+ * <td width="50%"><code>modifiers, name, arguments<br>
+ * RELATIVE_ORDER property</code></td>
+ * </tr>
+ * </table>
+ * Clients should not rely on the AST nodes being properly parented or on
+ * having source range information. (Future releases may provide options
+ * for requesting additional information like source positions, full ASTs,
+ * non-recursive sorting, etc.)
+ * </p>
+ *
+ * @param level the AST level; one of the AST LEVEL constants
+ * @param compilationUnit the given compilation unit, which must be a
+ * working copy
+ * @param positions an array of source positions to map, or
+ * <code>null</code> if none. If supplied, the positions must
+ * character-based source positions within the original source code for
+ * the given compilation unit, arranged in non-decreasing order.
+ * The array is updated in place when this method returns to reflect the
+ * corresponding source positions in the permuted source code string
+ * (but not necessarily any longer in non-decreasing order).
+ * @param comparator the comparator capable of ordering
+ * <code>BodyDeclaration</code>s; this comparator is passed AST nodes
+ * from an AST of the specified AST level
+ * @param options bitwise-or of option flags; <code>0</code> for default
+ * behavior (reserved for future growth)
+ * @param monitor the progress monitor to notify, or <code>null</code> if
+ * none
+ * @exception JavaModelException if the compilation unit could not be
+ * sorted. Reasons include:
+ * <ul>
+ * <li> The given compilation unit does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ * <li> The given compilation unit is not a working copy (INVALID_ELEMENT_TYPES)</li>
+ * <li> A <code>CoreException</code> occurred while accessing the underlying
+ * resource
+ * </ul>
+ * @exception IllegalArgumentException if the given compilation unit is null
+ * or if the given comparator is null, or if <code>level</code> is not one of
+ * the AST JLS level constants.
+ * @see org.eclipse.jdt.core.dom.BodyDeclaration
+ * @see #RELATIVE_ORDER
+ * @since 3.1
+ */
+ public static void sort(int level, ICompilationUnit compilationUnit,
+ int[] positions,
+ Comparator comparator,
+ int options,
+ IProgressMonitor monitor) throws JavaModelException {
+ if (compilationUnit == null || comparator == null) {
+ throw new IllegalArgumentException();
+ }
+ switch (level) {
+ case AST.JLS2 :
+ case AST.JLS3 :
+ break;
+ default :
+ throw new IllegalArgumentException();
+ }
+ ICompilationUnit[] compilationUnits = new ICompilationUnit[] { compilationUnit };
+ SortElementsOperation operation = new SortElementsOperation(level, compilationUnits, positions, comparator);
+ operation.runOperation(monitor);
+ }
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java
index 69d85d0..61fc861 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java
@@ -16,7 +16,7 @@
*
* This interface may be implemented by clients.
*
- * @since 3.0
+ * @since 3.1
*/
public interface IAnnotationComponentValue {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
index b0e42e9..a7a3cce 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
@@ -57,11 +57,7 @@
super(new ProblemReporter(
DefaultErrorHandlingPolicies.exitAfterAllProblems(),
options,
- problemFactory) {
- public void record(IProblem problem, CompilationResult unitResult) {
- requestor.acceptProblem(problem);
- }
- },
+ problemFactory),
false);
this.requestor = requestor;
intArrayStack = new int[30][];
@@ -1114,6 +1110,10 @@
}
return false;
}
+protected void parse() {
+ this.diet = true;
+ super.parse();
+}
/*
* Investigate one entire unit.
*/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
index 256ce09..79b2023 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
@@ -329,6 +329,20 @@
requestor.acceptFieldReference(fr.token, fr.sourceStart);
}
}
+protected void consumeMemberValuePair() {
+ super.consumeMemberValuePair();
+ MemberValuePair memberValuepair = (MemberValuePair) this.astStack[this.astPtr];
+ if (reportReferenceInfo) {
+ requestor.acceptMethodReference(memberValuepair.name, 0, memberValuepair.sourceStart);
+ }
+}
+protected void consumeMarkerAnnotation() {
+ super.consumeMarkerAnnotation();
+ Annotation annotation = (Annotation)expressionStack[expressionPtr];
+ if (reportReferenceInfo) { // accept annotation type reference
+ this.requestor.acceptTypeReference(annotation.type.getTypeName(), annotation.sourceStart, annotation.sourceEnd);
+ }
+}
protected void consumeMethodHeaderName(boolean isAnnotationMethod) {
long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
int selectorSourceEnd = (int) selectorSourcePositions;
@@ -435,6 +449,20 @@
(int)(messageSend.nameSourcePosition >>> 32));
}
}
+protected void consumeNormalAnnotation() {
+ super.consumeNormalAnnotation();
+ Annotation annotation = (Annotation)expressionStack[expressionPtr];
+ if (reportReferenceInfo) { // accept annotation type reference
+ this.requestor.acceptTypeReference(annotation.type.getTypeName(), annotation.sourceStart, annotation.sourceEnd);
+ }
+}
+protected void consumeSingleMemberAnnotation() {
+ super.consumeSingleMemberAnnotation();
+ SingleMemberAnnotation member = (SingleMemberAnnotation) expressionStack[expressionPtr];
+ if (reportReferenceInfo) {
+ requestor.acceptMethodReference(TypeConstants.VALUE, 0, member.sourceStart);
+ }
+}
protected void consumeSingleStaticImportDeclarationName() {
// SingleTypeImportDeclarationName ::= 'import' 'static' Name
super.consumeSingleStaticImportDeclarationName();
@@ -1104,6 +1132,8 @@
}
public void notifySourceElementRequestor(TypeDeclaration typeDeclaration, boolean notifyTypePresence, TypeDeclaration declaringType) {
+ if (CharOperation.equals(TypeConstants.PACKAGE_INFO_NAME, typeDeclaration.name)) return;
+
// range check
boolean isInRange =
scanner.initialPosition <= typeDeclaration.declarationSourceStart
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
index 42fe9e2..1c5015b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
@@ -34,35 +34,14 @@
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.ast.ASTNode;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ImportReference;
-import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
-import org.eclipse.jdt.internal.compiler.ast.TypeReference;
-import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.*;
-import org.eclipse.jdt.internal.compiler.env.ISourceImport;
-import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.core.*;
-import org.eclipse.jdt.internal.core.JavaElement;
-import org.eclipse.jdt.internal.core.SourceFieldElementInfo;
-import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
public class SourceTypeConverter implements CompilerModifiers {
@@ -82,12 +61,14 @@
private ICompilationUnit cu;
private char[] source;
private HashMap annotationPositions;
+ private boolean has1_5Compliance;
int namePos;
private SourceTypeConverter(int flags, ProblemReporter problemReporter) {
this.flags = flags;
this.problemReporter = problemReporter;
+ this.has1_5Compliance = problemReporter.options.complianceLevel >= ClassFileConstants.JDK1_5;
}
/*
@@ -128,7 +109,7 @@
this.cu = (ICompilationUnit) cuHandle;
this.annotationPositions = ((CompilationUnitElementInfo) ((JavaElement) this.cu).getElementInfo()).annotationPositions;
- if (this.annotationPositions != null && this.annotationPositions.size() > 10) { // experimental value
+ if (this.has1_5Compliance && this.annotationPositions != null && this.annotationPositions.size() > 10) { // experimental value
// if more than 10 annotations, diet parse as this is faster
return new Parser(this.problemReporter, true).dietParse(this.cu, compilationResult);
}
@@ -158,12 +139,17 @@
}
/* convert type(s) */
int typeCount = sourceTypes.length;
- this.unit.types = new TypeDeclaration[typeCount];
+ final TypeDeclaration[] types = new TypeDeclaration[typeCount];
+ /*
+ * We used a temporary types collection to prevent this.unit.types from being null during a call to
+ * convert(...) when the source is syntactically incorrect and the parser is flushing the unit's types.
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=97466
+ */
for (int i = 0; i < typeCount; i++) {
SourceTypeElementInfo typeInfo = (SourceTypeElementInfo) sourceTypes[i];
- this.unit.types[i] =
- convert((SourceType) typeInfo.getHandle(), compilationResult);
+ types[i] = convert((SourceType) typeInfo.getHandle(), compilationResult);
}
+ this.unit.types = types;
return this.unit;
}
@@ -232,8 +218,11 @@
field.type = createTypeReference(fieldInfo.getTypeName(), start, end);
}
- /* convert annotations */
- field.annotations = convertAnnotations(fieldHandle);
+ // convert 1.5 specific constructs only if compliance is 1.5 or above
+ if (this.has1_5Compliance) {
+ /* convert annotations */
+ field.annotations = convertAnnotations(fieldHandle);
+ }
/* conversion of field constant */
if ((this.flags & FIELD_INITIALIZATION) != 0) {
@@ -283,16 +272,19 @@
int start = methodInfo.getNameSourceStart();
int end = methodInfo.getNameSourceEnd();
- /* convert type parameters */
- char[][] typeParameterNames = methodInfo.getTypeParameterNames();
+ // convert 1.5 specific constructs only if compliance is 1.5 or above
TypeParameter[] typeParams = null;
- if (typeParameterNames != null) {
- int parameterCount = typeParameterNames.length;
- if (parameterCount > 0) { // method's type parameters must be null if no type parameter
- char[][][] typeParameterBounds = methodInfo.getTypeParameterBounds();
- typeParams = new TypeParameter[parameterCount];
- for (int i = 0; i < parameterCount; i++) {
- typeParams[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
+ if (this.has1_5Compliance) {
+ /* convert type parameters */
+ char[][] typeParameterNames = methodInfo.getTypeParameterNames();
+ if (typeParameterNames != null) {
+ int parameterCount = typeParameterNames.length;
+ if (parameterCount > 0) { // method's type parameters must be null if no type parameter
+ char[][][] typeParameterBounds = methodInfo.getTypeParameterBounds();
+ typeParams = new TypeParameter[parameterCount];
+ for (int i = 0; i < parameterCount; i++) {
+ typeParams[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
+ }
}
}
}
@@ -340,8 +332,11 @@
method.declarationSourceStart = methodInfo.getDeclarationSourceStart();
method.declarationSourceEnd = methodInfo.getDeclarationSourceEnd();
- /* convert annotations */
- method.annotations = convertAnnotations(methodHandle);
+ // convert 1.5 specific constructs only if compliance is 1.5 or above
+ if (this.has1_5Compliance) {
+ /* convert annotations */
+ method.annotations = convertAnnotations(methodHandle);
+ }
/* convert arguments */
String[] argumentTypeSignatures = methodHandle.getParameterTypes();
@@ -431,19 +426,23 @@
type.declarationSourceEnd = typeInfo.getDeclarationSourceEnd();
type.bodyEnd = type.declarationSourceEnd;
- /* convert annotations */
- type.annotations = convertAnnotations(typeHandle);
-
- /* convert type parameters */
- char[][] typeParameterNames = typeInfo.getTypeParameterNames();
- if (typeParameterNames.length > 0) {
- int parameterCount = typeParameterNames.length;
- char[][][] typeParameterBounds = typeInfo.getTypeParameterBounds();
- type.typeParameters = new TypeParameter[parameterCount];
- for (int i = 0; i < parameterCount; i++) {
- type.typeParameters[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
+ // convert 1.5 specific constructs only if compliance is 1.5 or above
+ if (this.has1_5Compliance) {
+ /* convert annotations */
+ type.annotations = convertAnnotations(typeHandle);
+
+ /* convert type parameters */
+ char[][] typeParameterNames = typeInfo.getTypeParameterNames();
+ if (typeParameterNames.length > 0) {
+ int parameterCount = typeParameterNames.length;
+ char[][][] typeParameterBounds = typeInfo.getTypeParameterBounds();
+ type.typeParameters = new TypeParameter[parameterCount];
+ for (int i = 0; i < parameterCount; i++) {
+ type.typeParameters[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
+ }
}
}
+
/* set superclass and superinterfaces */
if (typeInfo.getSuperclassName() != null) {
type.superclass = createTypeReference(typeInfo.getSuperclassName(), start, end);
@@ -555,13 +554,26 @@
if (positions == null) return null;
int length = positions.length;
Annotation[] annotations = new Annotation[length];
+ int recordedAnnotations = 0;
for (int i = 0; i < length; i++) {
long position = positions[i];
int start = (int) (position >>> 32);
int end = (int) position;
char[] annotationSource = CharOperation.subarray(cuSource, start, end+1);
Expression expression = parseMemberValue(annotationSource);
- annotations[i] = (Annotation) expression;
+ /*
+ * expression can be null or not an annotation if the source has changed between
+ * the moment where the annotation source positions have been retrieved and the moment were
+ * this parsing occured.
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=90916
+ */
+ if (expression instanceof Annotation) {
+ annotations[recordedAnnotations++] = (Annotation) expression;
+ }
+ }
+ if (length != recordedAnnotations) {
+ // resize to remove null annotations
+ System.arraycopy(annotations, 0, (annotations = new Annotation[recordedAnnotations]), 0, recordedAnnotations);
}
return annotations;
}
@@ -688,6 +700,9 @@
identCount ++;
break;
case '<' :
+ // convert 1.5 specific constructs only if compliance is 1.5 or above
+ if (!this.has1_5Compliance)
+ break typeLoop;
if (fragments == null) fragments = new ArrayList(2);
nameFragmentEnd = this.namePos-1;
char[][] identifiers = CharOperation.splitOn('.', typeName, nameFragmentStart, this.namePos);
@@ -699,6 +714,7 @@
nameFragmentStart = -1;
nameFragmentEnd = -1;
// next increment will skip '>'
+ break;
}
this.namePos++;
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java
index a196c93..6e5066c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java
@@ -60,7 +60,7 @@
return JavaElement.JEM_FIELD;
}
public String getKey(boolean forceOpen) throws JavaModelException {
- return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, forceOpen);
+ return getKey(this, forceOpen);
}
/*
* @see IField
@@ -88,7 +88,7 @@
/*
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
if (info == null) {
toStringName(buffer);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java
index 915b214..1cedf39 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java
@@ -155,7 +155,7 @@
return JavaElement.JEM_METHOD;
}
public String getKey(boolean forceOpen) throws JavaModelException {
- return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, forceOpen);
+ return getKey(this, forceOpen);
}
/*
* @see IMethod
@@ -331,7 +331,7 @@
}/*
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(tabString(tab));
if (info == null) {
toStringName(buffer);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
index 416f29f..8a49849 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
@@ -395,7 +395,7 @@
return NO_INITIALIZERS;
}
public String getKey(boolean forceOpen) throws JavaModelException {
- return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, forceOpen);
+ return getKey(this, forceOpen);
}
/*
* @see IType#getMethod(String name, String[] parameterTypeSignatures)
@@ -904,7 +904,7 @@
/*
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
if (info == null) {
toStringName(buffer);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java
index 2110dde..f62da56 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java
@@ -50,8 +50,8 @@
return super.findType(compoundTypeName);
}
- public void findTypes(char[] prefix, ISearchRequestor storage) {
+ public void findTypes(char[] prefix, boolean findMembers, ISearchRequestor storage) {
checkCanceled();
- super.findTypes(prefix, storage);
+ super.findTypes(prefix, findMembers, storage);
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
index 5f38317..66183fc 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
@@ -179,7 +179,7 @@
/*
* The extra attributes
*/
- private IClasspathAttribute[] extraAttributes;
+ IClasspathAttribute[] extraAttributes;
/**
* Creates a class path entry of the specified kind with the given path.
@@ -246,10 +246,14 @@
if (referringEntry.isExported() || referringEntry.getAccessRuleSet() != null ) {
boolean combine = this.entryKind == CPE_SOURCE || referringEntry.combineAccessRules();
return new ClasspathEntry(
- this.getContentKind(), this.getEntryKind(), this.getPath(),
+ getContentKind(),
+ getEntryKind(),
+ getPath(),
this.inclusionPatterns,
this.exclusionPatterns,
- this.getSourceAttachmentPath(), this.getSourceAttachmentRootPath(), this.getOutputLocation(),
+ getSourceAttachmentPath(),
+ getSourceAttachmentRootPath(),
+ getOutputLocation(),
referringEntry.isExported() || this.isExported, // duplicate container entry for tagging it as exported
combine(referringEntry.getAccessRules(), getAccessRules(), combine),
this.combineAccessRules,
@@ -261,7 +265,7 @@
private IAccessRule[] combine(IAccessRule[] referringRules, IAccessRule[] rules, boolean combine) {
if (!combine) return rules;
- if (rules == null) return referringRules;
+ if (rules == null || rules.length == 0) return referringRules;
// concat access rules
int referringRulesLength = referringRules.length;
@@ -274,7 +278,7 @@
return result;
}
- private static IClasspathAttribute[] decodeExtraAttributes(Element element) {
+ static IClasspathAttribute[] decodeExtraAttributes(Element element) {
Node extra = element.getElementsByTagName(TAG_ATTRIBUTES).item(0);
if (extra == null) return NO_EXTRA_ATTRIBUTES;
NodeList attributes = element.getElementsByTagName(TAG_ATTRIBUTE);
@@ -299,7 +303,7 @@
return result;
}
- private static IAccessRule[] decodeAccessRules(Element element) {
+ static IAccessRule[] decodeAccessRules(Element element) {
Node accessRules = element.getElementsByTagName(TAG_ACCESS_RULES).item(0);
if (accessRules == null || accessRules.getNodeType() != Node.ELEMENT_NODE) return null;
NodeList list = ((Element) accessRules).getElementsByTagName(TAG_ACCESS_RULE);
@@ -435,8 +439,8 @@
parameters.put(TAG_OUTPUT, String.valueOf(outputLocation));
}
- boolean hasExtraAttributes = this.extraAttributes != NO_EXTRA_ATTRIBUTES;
- boolean hasRestrictions = getAccessRuleSet() != null;
+ boolean hasExtraAttributes = this.extraAttributes.length != 0;
+ boolean hasRestrictions = getAccessRuleSet() != null; // access rule set is null if no access rules
writer.printTag(TAG_CLASSPATHENTRY, parameters, indent, newLine, !hasExtraAttributes && !hasRestrictions /*close tag if no extra attributes and no restriction*/);
if (hasExtraAttributes)
@@ -449,7 +453,7 @@
writer.endTag(TAG_CLASSPATHENTRY, indent);
}
- private void encodeExtraAttributes(XMLWriter writer, boolean indent, boolean newLine) {
+ void encodeExtraAttributes(XMLWriter writer, boolean indent, boolean newLine) {
writer.startTag(TAG_ATTRIBUTES, indent);
for (int i = 0; i < this.extraAttributes.length; i++) {
IClasspathAttribute attribute = this.extraAttributes[i];
@@ -461,7 +465,7 @@
writer.endTag(TAG_ATTRIBUTES, indent);
}
- private void encodeAccessRules(XMLWriter writer, boolean indent, boolean newLine) {
+ void encodeAccessRules(XMLWriter writer, boolean indent, boolean newLine) {
writer.startTag(TAG_ACCESS_RULES, indent);
AccessRule[] rules = getAccessRuleSet().getAccessRules();
@@ -614,7 +618,7 @@
null, // source attachment root
null, // custom output location
false,
- null,
+ null, // no access rules
false, // no accessible files to combine
NO_EXTRA_ATTRIBUTES);
default :
@@ -1224,7 +1228,7 @@
if (entryPath.equals(projectPath)){
// complain if self-referring project entry
if (kind == IClasspathEntry.CPE_PROJECT){
- return new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, Messages.bind(Messages.classpath_cannotReferToItself, new String[] {entryPath.makeRelative().toString()}));
+ return new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, Messages.bind(Messages.classpath_cannotReferToItself, entryPath.makeRelative().toString()));
}
// tolerate nesting output in src if src==prj
continue;
@@ -1360,6 +1364,18 @@
if (container == null){
return new JavaModelStatus(IJavaModelStatusConstants.CP_CONTAINER_PATH_UNBOUND, project, path);
} else if (container == JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
+ // Validate extra attributes
+ IClasspathAttribute[] extraAttributes = entry.getExtraAttributes();
+ if (extraAttributes != null) {
+ int length = extraAttributes.length;
+ HashSet set = new HashSet(length);
+ for (int i=0; i<length; i++) {
+ String attName = extraAttributes[i].getName();
+ if (!set.add(attName)) {
+ return new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryExtraAttribute, new String[] {attName, entryPathMsg, projectName}));
+ }
+ }
+ }
// don't create a marker if initialization is in progress (case of cp initialization batching)
return JavaModelStatus.VERIFIED_OK;
}
@@ -1446,8 +1462,8 @@
}
}
} else if (target instanceof File){
- File file = (File) target;
- if (!file.isFile()) {
+ File file = JavaModel.getFile(target);
+ if (file == null) {
return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalExternalFolder, new String[] {path.toOSString(), projectName}));
} else if (!org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(file.getName())) {
return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalLibraryArchive, (new String[] {path.toOSString(), projectName})));
@@ -1517,6 +1533,20 @@
}
break;
}
+
+ // Validate extra attributes
+ IClasspathAttribute[] extraAttributes = entry.getExtraAttributes();
+ if (extraAttributes != null) {
+ int length = extraAttributes.length;
+ HashSet set = new HashSet(length);
+ for (int i=0; i<length; i++) {
+ String attName = extraAttributes[i].getName();
+ if (!set.add(attName)) {
+ return new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryExtraAttribute, new String[] {attName, entryPathMsg, projectName}));
+ }
+ }
+ }
+
return JavaModelStatus.VERIFIED_OK;
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
index e320905..1345700 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
@@ -388,7 +388,8 @@
String source = ""; //$NON-NLS-1$
if (!pkg.isDefaultPackage()) {
//not the default package...add the package declaration
- source = "package " + pkg.getElementName() + ";" + org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR + org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR; //$NON-NLS-1$ //$NON-NLS-2$
+ String lineSeparator = Util.getLineSeparator(null/*no existing source*/, getJavaProject());
+ source = "package " + pkg.getElementName() + ";" + lineSeparator + lineSeparator; //$NON-NLS-1$ //$NON-NLS-2$
}
CreateCompilationUnitOperation op = new CreateCompilationUnitOperation(pkg, this.name, source, force);
op.runOperation(monitor);
@@ -578,7 +579,7 @@
public char[] getContents() {
try {
IBuffer buffer = this.getBuffer();
- return buffer == null ? null : buffer.getCharacters();
+ return buffer == null ? CharOperation.NO_CHAR : buffer.getCharacters();
} catch (JavaModelException e) {
return CharOperation.NO_CHAR;
}
@@ -1124,9 +1125,9 @@
}
}
/**
- * @private Debugging purposes
+ * Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
if (!isPrimary()) {
buffer.append(this.tabString(tab));
buffer.append("[Working copy] "); //$NON-NLS-1$
@@ -1140,7 +1141,7 @@
buffer.append(" (not open)"); //$NON-NLS-1$
}
} else {
- super.toStringInfo(tab, buffer, info);
+ super.toStringInfo(tab, buffer, info, showResolvedInfo);
}
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java
index 54fce6e..c93e061 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java
@@ -23,7 +23,6 @@
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
-import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.jdt.internal.core.util.Messages;
/**
@@ -103,14 +102,22 @@
String extension = path.getFileExtension();
return new RenameResourceElementsOperation(new IJavaElement[] {dest}, new IJavaElement[] {dest.getParent()}, new String[]{getNewNameFor(element) + '.' + extension}, this.force); //$NON-NLS-1$
} else {
- return new CreateTypeOperation(dest, getSourceFor(element) + Util.LINE_SEPARATOR, this.force);
+ String source = getSourceFor(element);
+ String lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(source, element.getJavaProject());
+ return new CreateTypeOperation(dest, source + lineSeparator, this.force);
}
case IJavaElement.METHOD :
- return new CreateMethodOperation((IType) dest, getSourceFor(element) + Util.LINE_SEPARATOR, this.force);
+ String source = getSourceFor(element);
+ String lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(source, element.getJavaProject());
+ return new CreateMethodOperation((IType) dest, source + lineSeparator, this.force);
case IJavaElement.FIELD :
- return new CreateFieldOperation((IType) dest, getSourceFor(element) + Util.LINE_SEPARATOR, this.force);
+ source = getSourceFor(element);
+ lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(source, element.getJavaProject());
+ return new CreateFieldOperation((IType) dest, source + lineSeparator, this.force);
case IJavaElement.INITIALIZER :
- return new CreateInitializerOperation((IType) dest, getSourceFor(element) + Util.LINE_SEPARATOR);
+ source = getSourceFor(element);
+ lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(source, element.getJavaProject());
+ return new CreateInitializerOperation((IType) dest, source + lineSeparator);
default :
return null;
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
index 386bf5c..cc3c386 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
@@ -299,7 +299,7 @@
if (!this.force) {
throw new JavaModelException(new JavaModelStatus(
IJavaModelStatusConstants.NAME_COLLISION,
- Messages.bind(Messages.status_nameCollision, (new String[] {destFile.getFullPath().toString()}))));
+ Messages.bind(Messages.status_nameCollision, destFile.getFullPath().toString())));
}
// update new resource content
// in case we do a saveas on the same resource we have to simply update the contents
@@ -439,7 +439,7 @@
} else {
throw new JavaModelException(new JavaModelStatus(
IJavaModelStatusConstants.NAME_COLLISION,
- Messages.bind(Messages.status_nameCollision, (new String[] {destinationResource.getFullPath().toString()}))));
+ Messages.bind(Messages.status_nameCollision, destinationResource.getFullPath().toString())));
}
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java
index bf939b6..f05a7d7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java
@@ -105,7 +105,7 @@
} else {
throw new JavaModelException(new JavaModelStatus(
IJavaModelStatusConstants.NAME_COLLISION,
- Messages.bind(Messages.status_nameCollision, (new String[] {compilationUnitFile.getFullPath().toString()}))));
+ Messages.bind(Messages.status_nameCollision, compilationUnitFile.getFullPath().toString())));
}
} else {
try {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java
index d75cb9f..b47da45 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java
@@ -11,6 +11,7 @@
package org.eclipse.jdt.internal.core;
import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModelStatus;
import org.eclipse.jdt.core.IJavaModelStatusConstants;
@@ -71,11 +72,19 @@
protected void initializeDefaultPosition() {
IType parentElement = getType();
try {
- IJavaElement[] elements = parentElement.getFields();
- if (elements != null && elements.length > 0) {
- createAfter(elements[elements.length - 1]);
+ IField[] fields = parentElement.getFields();
+ if (fields != null && fields.length > 0) {
+ final IField lastField = fields[fields.length - 1];
+ if (parentElement.isEnum()) {
+ IField field = lastField;
+ if (!field.isEnumConstant()) {
+ createAfter(lastField);
+ }
+ } else {
+ createAfter(lastField);
+ }
} else {
- elements = parentElement.getChildren();
+ IJavaElement[] elements = parentElement.getChildren();
if (elements != null && elements.length > 0) {
createBefore(elements[0]);
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java
index c0bfdf1..880565b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java
@@ -19,6 +19,7 @@
import org.eclipse.jdt.core.IJavaModelStatusConstants;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SimpleName;
@@ -55,14 +56,19 @@
protected String[] convertASTMethodTypesToSignatures() {
if (this.parameterTypes == null) {
if (this.createdNode != null) {
- List parameters = ((MethodDeclaration) this.createdNode).parameters();
+ MethodDeclaration methodDeclaration = (MethodDeclaration) this.createdNode;
+ List parameters = methodDeclaration.parameters();
int size = parameters.size();
this.parameterTypes = new String[size];
Iterator iterator = parameters.iterator();
// convert the AST types to signatures
for (int i = 0; i < size; i++) {
SingleVariableDeclaration parameter = (SingleVariableDeclaration) iterator.next();
- this.parameterTypes[i] = Util.getSignature(parameter.getType());
+ String typeSig = Util.getSignature(parameter.getType());
+ int extraDimensions = parameter.getExtraDimensions();
+ if (methodDeclaration.isVarargs() && i == size-1)
+ extraDimensions++;
+ this.parameterTypes[i] = Signature.createArraySignature(typeSig, extraDimensions);
}
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java
index 797263b..bdf6a41 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java
@@ -30,7 +30,6 @@
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
-import org.eclipse.jdt.internal.compiler.util.Util;
import org.eclipse.jdt.internal.core.dom.rewrite.Indents;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextUtilities;
@@ -151,9 +150,11 @@
protected String generateSyntaxIncorrectAST() {
//create some dummy source to generate an ast node
StringBuffer buff = new StringBuffer();
- buff.append(Util.LINE_SEPARATOR + " public class A {" + Util.LINE_SEPARATOR); //$NON-NLS-1$
+ IType type = getType();
+ String lineSeparator = org.eclipse.jdt.internal.core.util.Util.getLineSeparator(this.source, type == null ? null : type.getJavaProject());
+ buff.append(lineSeparator + " public class A {" + lineSeparator); //$NON-NLS-1$
buff.append(this.source);
- buff.append(Util.LINE_SEPARATOR).append('}');
+ buff.append(lineSeparator).append('}');
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(buff.toString().toCharArray());
CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
index 678ade5..607b963 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
@@ -10,23 +10,19 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.util.*;
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.Map;
import org.eclipse.core.resources.*;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.*;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.util.Util;
/**
@@ -70,6 +66,9 @@
/* A table from IPath (a source attachment path from a classpath entry) to IPath (a root path) */
public HashMap sourceAttachments = new HashMap();
+
+ /* A table from IJavaProject to IJavaProject[] (the list of direct dependent of the key) */
+ public HashMap projectDependencies = new HashMap();
/* Whether the roots tables should be recomputed */
public boolean rootsAreStale = true;
@@ -77,7 +76,7 @@
/* Threads that are currently running initializeRoots() */
private Set initializingThreads = Collections.synchronizedSet(new HashSet());
- public Hashtable externalTimeStamps = new Hashtable();
+ public Hashtable externalTimeStamps;
public HashMap projectUpdates = new HashMap();
@@ -232,6 +231,7 @@
HashMap newRoots = null;
HashMap newOtherRoots = null;
HashMap newSourceAttachments = null;
+ HashMap newProjectDependencies = null;
if (this.rootsAreStale) {
Thread currentThread = Thread.currentThread();
boolean addedCurrentThread = false;
@@ -248,6 +248,7 @@
newRoots = new HashMap();
newOtherRoots = new HashMap();
newSourceAttachments = new HashMap();
+ newProjectDependencies = new HashMap();
IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
IJavaProject[] projects;
@@ -268,7 +269,19 @@
}
for (int j= 0, classpathLength = classpath.length; j < classpathLength; j++) {
IClasspathEntry entry = classpath[j];
- if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) continue;
+ if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
+ IJavaProject key = model.getJavaProject(entry.getPath().segment(0)); // TODO (jerome) reuse handle
+ IJavaProject[] dependents = (IJavaProject[]) newProjectDependencies.get(key);
+ if (dependents == null) {
+ dependents = new IJavaProject[] {project};
+ } else {
+ int dependentsLength = dependents.length;
+ System.arraycopy(dependents, 0, dependents = new IJavaProject[dependentsLength+1], 0, dependentsLength);
+ dependents[dependentsLength] = project;
+ }
+ newProjectDependencies.put(key, dependents);
+ continue;
+ }
// root path
IPath path = entry.getPath();
@@ -317,6 +330,7 @@
this.roots = newRoots;
this.otherRoots = newOtherRoots;
this.sourceAttachments = newSourceAttachments;
+ this.projectDependencies = newProjectDependencies;
this.rootsAreStale = false;
}
}
@@ -424,6 +438,68 @@
}
}
+
+ public Hashtable getExternalLibTimeStamps() {
+ if (this.externalTimeStamps == null) {
+ Hashtable timeStamps = new Hashtable();
+ File timestampsFile = getTimeStampsFile();
+ DataInputStream in = null;
+ try {
+ in = new DataInputStream(new BufferedInputStream(new FileInputStream(timestampsFile)));
+ int size = in.readInt();
+ while (size-- > 0) {
+ String key = in.readUTF();
+ long timestamp = in.readLong();
+ timeStamps.put(Path.fromPortableString(key), new Long(timestamp));
+ }
+ } catch (IOException e) {
+ if (timestampsFile.exists())
+ Util.log(e, "Unable to read external time stamps"); //$NON-NLS-1$
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // nothing we can do: ignore
+ }
+ }
+ }
+ this.externalTimeStamps = timeStamps;
+ }
+ return this.externalTimeStamps;
+ }
+
+ private File getTimeStampsFile() {
+ return JavaCore.getPlugin().getStateLocation().append("externalLibsTimeStamps").toFile(); //$NON-NLS-1$
+ }
+
+ public void saveExternalLibTimeStamps() throws CoreException {
+ if (this.externalTimeStamps == null) return;
+ File timestamps = getTimeStampsFile();
+ DataOutputStream out = null;
+ try {
+ out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(timestamps)));
+ out.writeInt(this.externalTimeStamps.size());
+ Iterator keys = this.externalTimeStamps.keySet().iterator();
+ while (keys.hasNext()) {
+ IPath key = (IPath) keys.next();
+ out.writeUTF(key.toPortableString());
+ Long timestamp = (Long) this.externalTimeStamps.get(key);
+ out.writeLong(timestamp.longValue());
+ }
+ } catch (IOException e) {
+ IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving timestamps", e); //$NON-NLS-1$
+ throw new CoreException(status);
+ } finally {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ // nothing we can do: ignore
+ }
+ }
+ }
+ }
/*
* Update the roots that are affected by the addition or the removal of the given container resource.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
index 38cbb77..3b0356c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
@@ -12,10 +12,6 @@
import java.io.File;
import java.util.*;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
@@ -26,26 +22,15 @@
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.*;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.core.ElementChangedEvent;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IJavaElementDelta;
-import org.eclipse.jdt.core.IJavaModel;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.IPackageFragmentRoot;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.core.builder.JavaBuilder;
import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
import org.eclipse.jdt.internal.core.search.AbstractSearchScope;
+import org.eclipse.jdt.internal.core.search.JavaWorkspaceScope;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
import org.eclipse.jdt.internal.core.util.Util;
@@ -198,7 +183,7 @@
/*
* The Java model manager
*/
- private JavaModelManager manager;
+ JavaModelManager manager;
/*
* The <code>JavaElementDelta</code> corresponding to the <code>IResourceDelta</code> being translated.
@@ -263,31 +248,16 @@
* Adds the dependents of the given project to the list of the projects
* to update.
*/
- private void addDependentProjects(IPath projectPath, HashSet result) {
- IJavaProject[] projects = null;
- try {
- projects = this.manager.getJavaModel().getJavaProjects();
- } catch (JavaModelException e) {
- // java model doesn't exist
- return;
+ private void addDependentProjects(IJavaProject project, HashMap projectDependencies, HashSet result) {
+ IJavaProject[] dependents = (IJavaProject[]) projectDependencies.get(project);
+ if (dependents == null) return;
+ for (int i = 0, length = dependents.length; i < length; i++) {
+ IJavaProject dependent = dependents[i];
+ if (result.contains(dependent))
+ continue; // no need to go further as the project is already known
+ result.add(dependent);
+ addDependentProjects(dependent, projectDependencies, result);
}
- for (int i = 0, length = projects.length; i < length; i++) {
- IJavaProject project = projects[i];
- IClasspathEntry[] classpath = null;
- try {
- classpath = ((JavaProject)project).getExpandedClasspath(true);
- } catch (JavaModelException e) {
- // project doesn't exist: continue with next project
- continue;
- }
- for (int j = 0, length2 = classpath.length; j < length2; j++) {
- IClasspathEntry entry = classpath[j];
- if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT
- && entry.getPath().equals(projectPath)) {
- result.add(project);
- }
- }
- }
}
/*
* Adds the given element to the list of elements used as a scope for external jars refresh.
@@ -317,7 +287,7 @@
*/
private void addToRootsToRefreshWithDependents(IJavaProject javaProject) {
this.rootsToRefresh.add(javaProject);
- this.addDependentProjects(javaProject.getPath(), this.rootsToRefresh);
+ this.addDependentProjects(javaProject, this.state.projectDependencies, this.rootsToRefresh);
}
/*
* Check all external archive (referenced by given roots, projects or model) status and issue a corresponding root delta.
@@ -334,21 +304,39 @@
// force classpath marker refresh of affected projects
JavaModel.flushExternalFileCache();
IJavaElementDelta[] projectDeltas = this.currentDelta.getAffectedChildren();
- for (int i = 0, length = projectDeltas.length; i < length; i++) {
+ final int length = projectDeltas.length;
+ final IProject[] projectsToTouch = new IProject[length];
+ for (int i = 0; i < length; i++) {
IJavaElementDelta delta = projectDeltas[i];
JavaProject javaProject = (JavaProject)delta.getElement();
javaProject.getResolvedClasspath(
true/*ignoreUnresolvedEntry*/,
true/*generateMarkerOnError*/,
false/*don't returnResolutionInProgress*/);
-
- try {
- // touch the project to force it to be recompiled
- javaProject.getProject().touch(monitor);
- } catch (CoreException e) {
- throw new JavaModelException(e);
+ projectsToTouch[i] = javaProject.getProject();
+ }
+
+ // touch the projects to force them to be recompiled while taking the workspace lock
+ // so that there is no concurrency with the Java builder
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=96575
+ IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor progressMonitor) throws CoreException {
+ for (int i = 0; i < length; i++) {
+ IProject project = projectsToTouch[i];
+
+ // touch to force a build of this project
+ if (JavaBuilder.DEBUG)
+ System.out.println("Touching project " + project.getName() + " due to external jar file change"); //$NON-NLS-1$ //$NON-NLS-2$
+ project.touch(progressMonitor);
+ }
}
- }
+ };
+ try {
+ ResourcesPlugin.getWorkspace().run(runnable, monitor);
+ } catch (CoreException e) {
+ throw new JavaModelException(e);
+ }
+
if (this.currentDelta != null) { // if delta has not been fired while creating markers
this.fire(this.currentDelta, DEFAULT_CHANGE_EVENT);
}
@@ -799,7 +787,7 @@
Object targetLibrary = JavaModel.getTarget(wksRoot, entryPath, true);
if (targetLibrary == null){ // missing JAR
- if (this.state.externalTimeStamps.remove(entryPath) != null){
+ if (this.state.getExternalLibTimeStamps().remove(entryPath) != null){
externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
// the jar was physically removed: remove the index
this.manager.indexManager.removeIndex(entryPath);
@@ -810,19 +798,19 @@
File externalFile = (File)targetLibrary;
// check timestamp to figure if JAR has changed in some way
- Long oldTimestamp =(Long) this.state.externalTimeStamps.get(entryPath);
+ Long oldTimestamp =(Long) this.state.getExternalLibTimeStamps().get(entryPath);
long newTimeStamp = getTimeStamp(externalFile);
if (oldTimestamp != null){
if (newTimeStamp == 0){ // file doesn't exist
externalArchivesStatus.put(entryPath, EXTERNAL_JAR_REMOVED);
- this.state.externalTimeStamps.remove(entryPath);
+ this.state.getExternalLibTimeStamps().remove(entryPath);
// remove the index
this.manager.indexManager.removeIndex(entryPath);
} else if (oldTimestamp.longValue() != newTimeStamp){
externalArchivesStatus.put(entryPath, EXTERNAL_JAR_CHANGED);
- this.state.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
+ this.state.getExternalLibTimeStamps().put(entryPath, new Long(newTimeStamp));
// first remove the index so that it is forced to be re-indexed
this.manager.indexManager.removeIndex(entryPath);
// then index the jar
@@ -835,7 +823,7 @@
externalArchivesStatus.put(entryPath, EXTERNAL_JAR_UNCHANGED);
} else {
externalArchivesStatus.put(entryPath, EXTERNAL_JAR_ADDED);
- this.state.externalTimeStamps.put(entryPath, new Long(newTimeStamp));
+ this.state.getExternalLibTimeStamps().put(entryPath, new Long(newTimeStamp));
// index the new jar
this.manager.indexManager.indexLibrary(entryPath, project.getProject());
}
@@ -859,8 +847,6 @@
if (VERBOSE){
System.out.println("- External JAR CHANGED, affecting root: "+root.getElementName()); //$NON-NLS-1$
}
- // reset the corresponding project built state, since the builder would miss this change
- this.manager.setLastBuiltState(project.getProject(), null /*no state*/);
contentChanged(root);
hasDelta = true;
} else if (status == EXTERNAL_JAR_REMOVED) {
@@ -1193,6 +1179,17 @@
public void flush() {
this.javaModelDeltas = new ArrayList();
}
+ /* Returns the list of Java projects in the workspace.
+ *
+ */
+ IJavaProject[] getJavaProjects() {
+ try {
+ return this.manager.getJavaModel().getJavaProjects();
+ } catch (JavaModelException e) {
+ // java model doesn't exist
+ return new IJavaProject[0];
+ }
+ }
/*
* Finds the root info this path is included in.
* Returns null if not found.
@@ -1230,6 +1227,9 @@
AbstractSearchScope scope = (AbstractSearchScope)scopes.next();
scope.processDelta(deltaToNotify);
}
+ JavaWorkspaceScope workspaceScope = this.manager.workspaceScope;
+ if (workspaceScope != null)
+ workspaceScope.processDelta(deltaToNotify);
}
// Notification
@@ -1705,11 +1705,12 @@
*/
private void resetProjectCaches() {
Iterator iterator = this.projectCachesToReset.iterator();
+ HashMap projectDepencies = this.state.projectDependencies;
HashSet affectedDependents = new HashSet();
while (iterator.hasNext()) {
JavaProject project = (JavaProject)iterator.next();
project.resetCaches();
- addDependentProjects(project.getPath(), affectedDependents);
+ addDependentProjects(project, projectDepencies, affectedDependents);
}
// reset caches of dependent projects
iterator = affectedDependents.iterator();
@@ -2195,7 +2196,12 @@
if (deltaRes.getType() == IResource.PROJECT){
// reset the corresponding project built state, since cannot reuse if added back
+ if (JavaBuilder.DEBUG)
+ System.out.println("Clearing last state for removed project : " + deltaRes); //$NON-NLS-1$
this.manager.setLastBuiltState((IProject)deltaRes, null /*no state*/);
+
+ // clean up previous session containers (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89850)
+ this.manager.previousSessionContainers.remove(element);
}
return elementType == IJavaElement.PACKAGE_FRAGMENT;
case IResourceDelta.CHANGED :
@@ -2258,6 +2264,8 @@
this.manager.indexManager.discardJobs(element.getElementName());
this.manager.indexManager.removeIndexFamily(res.getFullPath());
// reset the corresponding project built state, since cannot reuse if added back
+ if (JavaBuilder.DEBUG)
+ System.out.println("Clearing last state for project loosing Java nature: " + res); //$NON-NLS-1$
this.manager.setLastBuiltState(res, null /*no state*/);
}
return false; // when a project's nature is added/removed don't process children
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
index 82efebf..47a90aa 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
@@ -110,7 +110,7 @@
/**
* Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
buffer.append("<import container>"); //$NON-NLS-1$
if (info == null) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java
index 3d33bce..5b86608 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java
@@ -101,7 +101,7 @@
/**
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
buffer.append("import "); //$NON-NLS-1$
toStringName(buffer);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java
index de25ee6..ee1953a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java
@@ -92,7 +92,7 @@
/**
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
if (info == null) {
buffer.append("<initializer #"); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
index a13b85a..32f0765 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
@@ -83,7 +83,7 @@
defaultOptionsMap.put(JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES, ""); //$NON-NLS-1$
defaultOptionsMap.put(JavaCore.CODEASSIST_LOCAL_SUFFIXES, ""); //$NON-NLS-1$
defaultOptionsMap.put(JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, ""); //$NON-NLS-1$
- defaultOptionsMap.put(JavaCore.CODEASSIST_FORBIDDEN_REFERENCE_CHECK, JavaCore.DISABLED); //$NON-NLS-1$
+ defaultOptionsMap.put(JavaCore.CODEASSIST_FORBIDDEN_REFERENCE_CHECK, JavaCore.ENABLED); //$NON-NLS-1$
defaultOptionsMap.put(JavaCore.CODEASSIST_DISCOURAGED_REFERENCE_CHECK, JavaCore.DISABLED); //$NON-NLS-1$
// Store default values to default preferences
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceModifyListener.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceModifyListener.java
new file mode 100644
index 0000000..3e0b2aa
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceModifyListener.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.core.runtime.preferences.PreferenceModifyListener;
+import org.eclipse.jdt.core.*;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+public class JavaCorePreferenceModifyListener extends PreferenceModifyListener {
+
+ static int PREFIX_LENGTH = JavaModelManager.CP_CONTAINER_PREFERENCES_PREFIX.length();
+ JavaModel javaModel = JavaModelManager.getJavaModelManager().getJavaModel();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.preferences.PreferenceModifyListener#preApply(org.eclipse.core.runtime.preferences.IEclipsePreferences)
+ */
+ public IEclipsePreferences preApply(IEclipsePreferences node) {
+ Preferences instance = node.node(InstanceScope.SCOPE);
+ cleanJavaCore(instance.node(JavaCore.PLUGIN_ID));
+ return super.preApply(node);
+ }
+
+ /**
+ * Clean imported preferences from obsolete keys.
+ *
+ * @param preferences JavaCore preferences.
+ */
+ void cleanJavaCore(Preferences preferences) {
+ try {
+ String[] keys = preferences.keys();
+ for (int k = 0, kl= keys.length; k<kl; k++) {
+ String key = keys[k];
+ if (key.startsWith(JavaModelManager.CP_CONTAINER_PREFERENCES_PREFIX) && !isJavaProjectAccessible(key)) {
+ preferences.remove(key);
+ }
+ }
+ } catch (BackingStoreException e) {
+ // do nothing
+ }
+ }
+
+ /**
+ * Returns whether a java project referenced in property key
+ * is still longer accessible or not.
+ *
+ * @param propertyName
+ * @return true if a project is referenced in given key and this project
+ * is still accessible, false otherwise.
+ */
+ boolean isJavaProjectAccessible(String propertyName) {
+ int index = propertyName.indexOf('|', PREFIX_LENGTH);
+ if (index > 0) {
+ final String projectName = propertyName.substring(PREFIX_LENGTH, index).trim();
+ JavaProject project = (JavaProject) javaModel.getJavaProject(projectName);
+ if (project.getProject().isAccessible()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
index 5a5a4f8..06fad7f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
@@ -527,7 +527,7 @@
*/
public String toDebugString() {
StringBuffer buffer = new StringBuffer();
- this.toStringInfo(0, buffer, NO_INFO);
+ this.toStringInfo(0, buffer, NO_INFO, true/*show resolved info*/);
return buffer.toString();
}
/**
@@ -552,8 +552,14 @@
* Debugging purposes
*/
public String toStringWithAncestors() {
+ return toStringWithAncestors(true/*show resolved info*/);
+ }
+ /**
+ * Debugging purposes
+ */
+ public String toStringWithAncestors(boolean showResolvedInfo) {
StringBuffer buffer = new StringBuffer();
- this.toStringInfo(0, buffer, NO_INFO);
+ this.toStringInfo(0, buffer, NO_INFO, showResolvedInfo);
this.toStringAncestors(buffer);
return buffer.toString();
}
@@ -564,7 +570,7 @@
JavaElement parentElement = (JavaElement)this.getParent();
if (parentElement != null && parentElement.getParent() != null) {
buffer.append(" [in "); //$NON-NLS-1$
- parentElement.toStringInfo(0, buffer, NO_INFO);
+ parentElement.toStringInfo(0, buffer, NO_INFO, false/*don't show resolved info*/);
parentElement.toStringAncestors(buffer);
buffer.append("]"); //$NON-NLS-1$
}
@@ -585,13 +591,14 @@
*/
public Object toStringInfo(int tab, StringBuffer buffer) {
Object info = JavaModelManager.getJavaModelManager().peekAtInfo(this);
- this.toStringInfo(tab, buffer, info);
+ this.toStringInfo(tab, buffer, info, true/*show resolved info*/);
return info;
}
/**
* Debugging purposes
+ * @param showResolvedInfo TODO
*/
- protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+ protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
toStringName(buffer);
if (info == null) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
index b3855da..cbebfbe 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
@@ -49,7 +49,14 @@
* Note this cache is kept for the whole session.
*/
public static HashSet existingExternalFiles = new HashSet();
-
+
+ /**
+ * A set of external files ({@link #existingExternalFiles}) which have
+ * been confirmed as file (ie. which returns true to {@link java.io.File#isFile()}.
+ * Note this cache is kept for the whole session.
+ */
+ public static HashSet existingExternalConfirmedFiles = new HashSet();
+
/**
* Constructs a new Java Model on the given workspace.
* Note that only one instance of JavaModel handle should ever be created.
@@ -160,6 +167,7 @@
*/
public static void flushExternalFileCache() {
existingExternalFiles = new HashSet();
+ existingExternalConfirmedFiles = new HashSet();
}
/*
@@ -317,7 +325,7 @@
/**
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
buffer.append("Java Model"); //$NON-NLS-1$
if (info == null) {
@@ -367,4 +375,29 @@
}
return null;
}
+
+/**
+ * Helper method - returns whether an object is afile (ie. which returns true to {@link java.io.File#isFile()}.
+ */
+public static boolean isFile(Object target) {
+ return getFile(target) != null;
+}
+
+/**
+ * Helper method - returns the file item (ie. which returns true to {@link java.io.File#isFile()},
+ * or null if unbound
+ */
+public static File getFile(Object target) {
+ if (existingExternalConfirmedFiles.contains(target))
+ return (File) target;
+ if (target instanceof File) {
+ File f = (File) target;
+ if (f.isFile()) {
+ existingExternalConfirmedFiles.add(f);
+ return f;
+ }
+ }
+
+ return null;
+}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index 0e9c077..c1758f4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -20,8 +20,10 @@
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.CharOperation;
@@ -35,6 +37,7 @@
import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
import org.eclipse.jdt.internal.core.search.AbstractSearchScope;
import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
+import org.eclipse.jdt.internal.core.search.JavaWorkspaceScope;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
import org.eclipse.jdt.internal.core.search.processing.JobManager;
import org.eclipse.jdt.internal.core.util.Messages;
@@ -75,6 +78,7 @@
public HashMap previousSessionContainers = new HashMap(5);
private ThreadLocal containerInitializationInProgress = new ThreadLocal();
public boolean batchContainerInitializations = false;
+ public HashMap containerInitializersCache = new HashMap(5);
/*
* A HashSet that contains the IJavaProject whose classpath is being resolved.
@@ -82,6 +86,11 @@
private ThreadLocal classpathsBeingResolved = new ThreadLocal();
/*
+ * The unique workspace scope
+ */
+ public JavaWorkspaceScope workspaceScope;
+
+ /*
* Pools of symbols used in the Java model.
* Used as a replacement for String#intern() that could prevent garbage collection of strings on some VMs.
*/
@@ -91,6 +100,8 @@
public final static String CP_VARIABLE_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathVariable."; //$NON-NLS-1$
public final static String CP_CONTAINER_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$
public final static String CP_ENTRY_IGNORE = "##<cp entry ignore>##"; //$NON-NLS-1$
+
+ private final static int VARIABLES_AND_CONTAINERS_FILE_VERSION = 1;
/**
* Name of the extension point for contributing classpath variable initializers
@@ -139,6 +150,7 @@
private static final String RESOLUTION_DEBUG = JavaCore.PLUGIN_ID + "/debug/resolution" ; //$NON-NLS-1$
private static final String SELECTION_DEBUG = JavaCore.PLUGIN_ID + "/debug/selection" ; //$NON-NLS-1$
private static final String SEARCH_DEBUG = JavaCore.PLUGIN_ID + "/debug/search" ; //$NON-NLS-1$
+ private static final String SOURCE_MAPPER_DEBUG_VERBOSE = JavaCore.PLUGIN_ID + "/debug/sourcemapper" ; //$NON-NLS-1$
public static final String COMPLETION_PERF = JavaCore.PLUGIN_ID + "/perf/completion" ; //$NON-NLS-1$
public static final String SELECTION_PERF = JavaCore.PLUGIN_ID + "/perf/selection" ; //$NON-NLS-1$
@@ -153,7 +165,9 @@
public final static ICompilationUnit[] NO_WORKING_COPY = new ICompilationUnit[0];
// Preferences
- public HashSet optionNames = new HashSet(20);
+ HashSet optionNames = new HashSet(20);
+ Hashtable optionsCache;
+
public final IEclipsePreferences[] preferencesLookup = new IEclipsePreferences[2];
static final int PREF_INSTANCE = 0;
static final int PREF_DEFAULT = 1;
@@ -237,18 +251,14 @@
public synchronized void containerPut(IJavaProject project, IPath containerPath, IClasspathContainer container){
// set/unset the initialization in progress
- HashSet projectInitializations = containerInitializationInProgress(project);
if (container == CONTAINER_INITIALIZATION_IN_PROGRESS) {
+ HashSet projectInitializations = containerInitializationInProgress(project);
projectInitializations.add(containerPath);
// do not write out intermediate initialization value
return;
} else {
- projectInitializations.remove(containerPath);
- if (projectInitializations.size() == 0) {
- Map initializations = (Map)this.containerInitializationInProgress.get();
- initializations.remove(project);
- }
+ containerRemoveInitializationInProgress(project, containerPath);
Map projectContainers = (Map)this.containers.get(project);
if (projectContainers == null){
@@ -358,6 +368,15 @@
return true;
}
+ private void containerRemoveInitializationInProgress(IJavaProject project, IPath containerPath) {
+ HashSet projectInitializations = containerInitializationInProgress(project);
+ projectInitializations.remove(containerPath);
+ if (projectInitializations.size() == 0) {
+ Map initializations = (Map)this.containerInitializationInProgress.get();
+ initializations.remove(project);
+ }
+ }
+
private synchronized void containersReset(String[] containerIDs) {
for (int i = 0; i < containerIDs.length; i++) {
String containerID = containerIDs[i];
@@ -464,10 +483,29 @@
if (folder == null) {
return null;
}
+ IJavaElement element;
if (project == null) {
project = JavaCore.create(folder.getProject());
+ element = determineIfOnClasspath(folder, project);
+ if (element == null) {
+ // walk all projects and find one that have the given folder on its classpath
+ IJavaProject[] projects;
+ try {
+ projects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects();
+ } catch (JavaModelException e) {
+ return null;
+ }
+ for (int i = 0, length = projects.length; i < length; i++) {
+ project = projects[i];
+ element = determineIfOnClasspath(folder, project);
+ if (element != null)
+ break;
+ }
+ }
+ } else {
+ element = determineIfOnClasspath(folder, project);
}
- IJavaElement element = determineIfOnClasspath(folder, project);
+
if (conflictsWithOutputLocation(folder.getFullPath(), (JavaProject)project)
|| (folder.getName().indexOf('.') >= 0
&& !(element instanceof IPackageFragmentRoot))) {
@@ -608,7 +646,7 @@
/**
* The singleton manager
*/
- private final static JavaModelManager MANAGER= new JavaModelManager();
+ private static JavaModelManager MANAGER= new JavaModelManager();
/**
* Infos cache.
@@ -669,6 +707,26 @@
this.project = project;
}
+ public void rememberExternalLibTimestamps() {
+ IClasspathEntry[] classpath = this.resolvedClasspath;
+ if (classpath == null) return;
+ IWorkspaceRoot wRoot = ResourcesPlugin.getWorkspace().getRoot();
+ Map externalTimeStamps = JavaModelManager.getJavaModelManager().deltaState.getExternalLibTimeStamps();
+ for (int i = 0, length = classpath.length; i < length; i++) {
+ IClasspathEntry entry = classpath[i];
+ if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+ IPath path = entry.getPath();
+ if (externalTimeStamps.get(path) == null) {
+ Object target = JavaModel.getTarget(wRoot, path, true);
+ if (target instanceof java.io.File) {
+ long timestamp = DeltaProcessor.getTimeStamp((java.io.File)target);
+ externalTimeStamps.put(path, new Long(timestamp));
+ }
+ }
+ }
+ }
+ }
+
// updating raw classpath need to flush obsoleted cached information about resolved entries
public synchronized void updateClasspathInformation(IClasspathEntry[] newRawClasspath) {
@@ -792,6 +850,14 @@
}
/**
+ * @deprecated
+ */
+ private void addDeprecatedOptions(Hashtable options) {
+ options.put(JavaCore.COMPILER_PB_INVALID_IMPORT, JavaCore.ERROR);
+ options.put(JavaCore.COMPILER_PB_UNREACHABLE_CODE, JavaCore.ERROR);
+ }
+
+ /**
* Starts caching ZipFiles.
* Ignores if there are already clients.
*/
@@ -863,6 +929,9 @@
option = Platform.getDebugOption(ZIP_ACCESS_DEBUG);
if(option != null) JavaModelManager.ZIP_ACCESS_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+
+ option = Platform.getDebugOption(SOURCE_MAPPER_DEBUG_VERBOSE);
+ if(option != null) SourceMapper.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
}
// configure performance options
@@ -1009,6 +1078,28 @@
return preferencesLookup[PREF_INSTANCE];
}
+ public Hashtable getDefaultOptions(){
+
+ Hashtable defaultOptions = new Hashtable(10);
+
+ // see JavaCorePreferenceInitializer#initializeDefaultPluginPreferences() for changing default settings
+ IEclipsePreferences defaultPreferences = getDefaultPreferences();
+
+ // initialize preferences to their default
+ Iterator iterator = this.optionNames.iterator();
+ while (iterator.hasNext()) {
+ String propertyName = (String) iterator.next();
+ String value = defaultPreferences.get(propertyName, null);
+ if (value != null) defaultOptions.put(propertyName, value);
+ }
+ // get encoding through resource plugin
+ defaultOptions.put(JavaCore.CORE_ENCODING, JavaCore.getEncoding());
+ // backward compatibility
+ addDeprecatedOptions(defaultOptions);
+
+ return defaultOptions;
+ }
+
/**
* Get default eclipse preference for JavaCore plugin.
*/
@@ -1037,7 +1128,11 @@
* For use by image builder and evaluation support only
*/
public Object getLastBuiltState(IProject project, IProgressMonitor monitor) {
- if (!JavaProject.hasJavaNature(project)) return null; // should never be requested on non-Java projects
+ if (!JavaProject.hasJavaNature(project)) {
+ if (JavaBuilder.DEBUG)
+ System.out.println(project + " is not a Java project"); //$NON-NLS-1$
+ return null; // should never be requested on non-Java projects
+ }
PerProjectInfo info = getPerProjectInfo(project, true/*create if missing*/);
if (!info.triedRead) {
info.triedRead = true;
@@ -1052,6 +1147,56 @@
return info.savedState;
}
+ public String getOption(String optionName) {
+
+ if (JavaCore.CORE_ENCODING.equals(optionName)){
+ return JavaCore.getEncoding();
+ }
+ // backward compatibility
+ if (isDeprecatedOption(optionName)) {
+ return JavaCore.ERROR;
+ }
+ String propertyName = optionName;
+ if (this.optionNames.contains(propertyName)){
+ IPreferencesService service = Platform.getPreferencesService();
+ String value = service.get(optionName, null, this.preferencesLookup);
+ return value==null ? null : value.trim();
+ }
+ return null;
+ }
+
+ public Hashtable getOptions() {
+
+ // return cached options if already computed
+ if (this.optionsCache != null) return new Hashtable(this.optionsCache);
+
+ // init
+ Hashtable options = new Hashtable(10);
+ IPreferencesService service = Platform.getPreferencesService();
+
+ // set options using preferences service lookup
+ Iterator iterator = optionNames.iterator();
+ while (iterator.hasNext()) {
+ String propertyName = (String) iterator.next();
+ String propertyValue = service.get(propertyName, null, this.preferencesLookup);
+ if (propertyValue != null) {
+ options.put(propertyName, propertyValue);
+ }
+ }
+
+ // get encoding through resource plugin
+ options.put(JavaCore.CORE_ENCODING, JavaCore.getEncoding());
+
+ // backward compatibility
+ addDeprecatedOptions(options);
+
+ // store built map in cache
+ this.optionsCache = new Hashtable(options);
+
+ // return built map
+ return options;
+ }
+
/*
* Returns the per-project info for the given project. If specified, create the info if the info doesn't exist.
*/
@@ -1173,6 +1318,10 @@
}
return result;
}
+
+ private File getVariableAndContainersFile() {
+ return JavaCore.getPlugin().getStateLocation().append("variablesAndContainers.dat").toFile(); //$NON-NLS-1$
+ }
/**
* Returns the name of the variables for which an CP variable initializer is registered through an extension point
@@ -1248,11 +1397,18 @@
int primaryLength = primaryWCs == null ? 0 : primaryWCs.length;
int size = workingCopyToInfos.size(); // note size is > 0 otherwise pathToPerWorkingCopyInfos would be null
ICompilationUnit[] result = new ICompilationUnit[primaryLength + size];
+ int index = 0;
if (primaryWCs != null) {
- System.arraycopy(primaryWCs, 0, result, 0, primaryLength);
+ for (int i = 0; i < primaryLength; i++) {
+ ICompilationUnit primaryWorkingCopy = primaryWCs[i];
+ ICompilationUnit workingCopy = new CompilationUnit((PackageFragment) primaryWorkingCopy.getParent(), primaryWorkingCopy.getElementName(), owner);
+ if (!workingCopyToInfos.containsKey(workingCopy))
+ result[index++] = primaryWorkingCopy;
+ }
+ if (index != primaryLength)
+ System.arraycopy(result, 0, result = new ICompilationUnit[index+size], 0, index);
}
Iterator iterator = workingCopyToInfos.values().iterator();
- int index = primaryLength;
while(iterator.hasNext()) {
result[index++] = ((JavaModelManager.PerWorkingCopyInfo)iterator.next()).getWorkingCopy();
}
@@ -1260,6 +1416,13 @@
}
}
+ public JavaWorkspaceScope getWorkspaceScope() {
+ if (this.workspaceScope == null) {
+ this.workspaceScope = new JavaWorkspaceScope();
+ }
+ return this.workspaceScope;
+ }
+
/**
* Returns the open ZipFile at the given location. If the ZipFile
* does not yet exist, it is created, opened, and added to the cache
@@ -1345,6 +1508,9 @@
paths.add(path);
}
}
+ /* TODO (frederic) put back when JDT/UI dummy project will be thrown away...
+ * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=97524
+ *
if (javaProject.equals(javaProjectToInit)) {
if (paths == null) {
paths = new HashSet();
@@ -1352,7 +1518,16 @@
}
paths.add(containerToInit);
}
+ */
}
+ // TODO (frederic) remove following block when JDT/UI dummy project will be thrown away...
+ HashSet containerPaths = (HashSet) allContainerPaths.get(javaProjectToInit);
+ if (containerPaths == null) {
+ containerPaths = new HashSet();
+ allContainerPaths.put(javaProjectToInit, containerPaths);
+ }
+ containerPaths.add(containerToInit);
+ // end block
// mark all containers as being initialized
this.containerInitializationInProgress.set(allContainerPaths);
@@ -1440,7 +1615,9 @@
stats.endRun();
}
if (!ok) {
- containerPut(project, containerPath, null); // flush cache
+ // just remove initialization in progress and keep previous session container so as to avoid a full build
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=92588
+ containerRemoveInitializationInProgress(project, containerPath);
if (CP_RESOLVE_VERBOSE) {
if (container == CONTAINER_INITIALIZATION_IN_PROGRESS) {
Util.verbose(
@@ -1562,6 +1739,14 @@
return getClasspathBeingResolved().contains(project);
}
+ /**
+ * @deprecated
+ */
+ private boolean isDeprecatedOption(String optionName) {
+ return JavaCore.COMPILER_PB_INVALID_IMPORT.equals(optionName)
+ || JavaCore.COMPILER_PB_UNREACHABLE_CODE.equals(optionName);
+ }
+
public void setClasspathBeingResolved(IJavaProject project, boolean classpathIsResolved) {
if (classpathIsResolved) {
getClasspathBeingResolved().add(project);
@@ -1571,7 +1756,6 @@
}
public void loadVariablesAndContainers() throws CoreException {
-
// backward compatibility, consider persistent property
QualifiedName qName = new QualifiedName(JavaCore.PLUGIN_ID, "variables"); //$NON-NLS-1$
String xmlString = ResourcesPlugin.getWorkspace().getRoot().getPersistentProperty(qName);
@@ -1616,14 +1800,12 @@
if (xmlString != null){
ResourcesPlugin.getWorkspace().getRoot().setPersistentProperty(qName, null); // flush old one
}
-
}
-
- // load variables and containers from preferences into cache
- IEclipsePreferences preferences = getInstancePreferences();
- // only get variable from preferences not set to their default
+ // backward compatibility, load variables and containers from preferences into cache
+ IEclipsePreferences preferences = getInstancePreferences();
try {
+ // only get variable from preferences not set to their default
String[] propertyNames = preferences.keys();
int variablePrefixLength = CP_VARIABLE_PREFERENCES_PREFIX.length();
for (int i = 0; i < propertyNames.length; i++){
@@ -1632,20 +1814,82 @@
String varName = propertyName.substring(variablePrefixLength);
String propertyValue = preferences.get(propertyName, null);
if (propertyValue != null) {
- IPath varPath = new Path(propertyValue.trim());
+ String pathString = propertyValue.trim();
+
+ if (CP_ENTRY_IGNORE.equals(pathString)) {
+ // cleanup old preferences
+ preferences.remove(propertyName);
+ continue;
+ }
+
+ // add variable to table
+ IPath varPath = new Path(pathString);
this.variables.put(varName, varPath);
this.previousSessionVariables.put(varName, varPath);
}
- }
- if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)){
+ } else if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)){
String propertyValue = preferences.get(propertyName, null);
- if (propertyValue != null)
+ if (propertyValue != null) {
+ // cleanup old preferences
+ preferences.remove(propertyName);
+
+ // recreate container
recreatePersistedContainer(propertyName, propertyValue, true/*add to container values*/);
+ }
}
}
} catch (BackingStoreException e1) {
// TODO (frederic) see if it's necessary to report this failure...
}
+
+ // load variables and containers from saved file into cache
+ File file = getVariableAndContainersFile();
+ DataInputStream in = null;
+ try {
+ in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
+ if (VARIABLES_AND_CONTAINERS_FILE_VERSION == in.readInt()) {
+
+ // variables
+ int size = in.readInt();
+ while (size-- > 0) {
+ String varName = in.readUTF();
+ String pathString = in.readUTF();
+ if (CP_ENTRY_IGNORE.equals(pathString))
+ continue;
+ IPath varPath = Path.fromPortableString(pathString);
+ this.variables.put(varName, varPath);
+ this.previousSessionVariables.put(varName, varPath);
+ }
+
+ // containers
+ IJavaModel model = getJavaModel();
+ int projectSize = in.readInt();
+ while (projectSize-- > 0) {
+ String projectName = in.readUTF();
+ IJavaProject project = model.getJavaProject(projectName);
+ int containerSize = in.readInt();
+ while (containerSize-- > 0) {
+ IPath containerPath = Path.fromPortableString(in.readUTF());
+ int length = in.readInt();
+ byte[] containerString = new byte[length];
+ in.readFully(containerString);
+ recreatePersistedContainer(project, containerPath, new String(containerString), true/*add to container values*/);
+ }
+ }
+ }
+ } catch (IOException e) {
+ if (file.exists())
+ Util.log(e, "Unable to read variable and containers file"); //$NON-NLS-1$
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // nothing we can do: ignore
+ }
+ }
+ }
+
// override persisted values for variables which have a registered initializer
String[] registeredVariables = getRegisteredVariableNames();
for (int i = 0; i < registeredVariables.length; i++) {
@@ -1733,6 +1977,11 @@
e.printStackTrace();
throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR, "Error reading last build state for project "+ project.getName(), e)); //$NON-NLS-1$
}
+ } else if (JavaBuilder.DEBUG) {
+ if (file == null)
+ System.out.println("Project does not exist: " + project); //$NON-NLS-1$
+ else
+ System.out.println("Build state file " + file.getPath() + " does not exist"); //$NON-NLS-1$ //$NON-NLS-2$
}
return null;
}
@@ -1742,44 +1991,47 @@
int index = propertyName.indexOf('|', containerPrefixLength);
if (containerString != null) containerString = containerString.trim();
if (index > 0) {
- final String projectName = propertyName.substring(containerPrefixLength, index).trim();
- JavaProject project = (JavaProject)getJavaModelManager().getJavaModel().getJavaProject(projectName);
- if (!project.getProject().isAccessible()) return; // avoid leaking deleted project's persisted container
- final IPath containerPath = new Path(propertyName.substring(index+1).trim());
-
- if (containerString == null || containerString.equals(CP_ENTRY_IGNORE)) {
- getJavaModelManager().containerPut(project, containerPath, null);
- } else {
- final IClasspathEntry[] containerEntries = project.decodeClasspath(containerString, false, false);
- if (containerEntries != null && containerEntries != JavaProject.INVALID_CLASSPATH) {
- IClasspathContainer container = new IClasspathContainer() {
- public IClasspathEntry[] getClasspathEntries() {
- return containerEntries;
- }
- public String getDescription() {
- return "Persisted container ["+containerPath+" for project ["+ projectName+"]"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
- }
- public int getKind() {
- return 0;
- }
- public IPath getPath() {
- return containerPath;
- }
- public String toString() {
- return getDescription();
- }
+ String projectName = propertyName.substring(containerPrefixLength, index).trim();
+ IJavaProject project = getJavaModelManager().getJavaModel().getJavaProject(projectName);
+ IPath containerPath = new Path(propertyName.substring(index+1).trim());
+ recreatePersistedContainer(project, containerPath, containerString, addToContainerValues);
+ }
+ }
+
+ private static void recreatePersistedContainer(final IJavaProject project, final IPath containerPath, String containerString, boolean addToContainerValues) {
+ if (!project.getProject().isAccessible()) return; // avoid leaking deleted project's persisted container
+ if (containerString == null) {
+ getJavaModelManager().containerPut(project, containerPath, null);
+ } else {
+ final IClasspathEntry[] containerEntries = ((JavaProject) project).decodeClasspath(containerString, false, false);
+ if (containerEntries != null && containerEntries != JavaProject.INVALID_CLASSPATH) {
+ IClasspathContainer container = new IClasspathContainer() {
+ public IClasspathEntry[] getClasspathEntries() {
+ return containerEntries;
+ }
+ public String getDescription() {
+ return "Persisted container ["+containerPath+" for project ["+ project.getElementName()+"]"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ }
+ public int getKind() {
+ return 0;
+ }
+ public IPath getPath() {
+ return containerPath;
+ }
+ public String toString() {
+ return getDescription();
+ }
- };
- if (addToContainerValues) {
- getJavaModelManager().containerPut(project, containerPath, container);
- }
- Map projectContainers = (Map)getJavaModelManager().previousSessionContainers.get(project);
- if (projectContainers == null){
- projectContainers = new HashMap(1);
- getJavaModelManager().previousSessionContainers.put(project, projectContainers);
- }
- projectContainers.put(containerPath, container);
+ };
+ if (addToContainerValues) {
+ getJavaModelManager().containerPut(project, containerPath, container);
}
+ Map projectContainers = (Map)getJavaModelManager().previousSessionContainers.get(project);
+ if (projectContainers == null){
+ projectContainers = new HashMap(1);
+ getJavaModelManager().previousSessionContainers.put(project, projectContainers);
+ }
+ projectContainers.put(containerPath, container);
}
}
}
@@ -1884,6 +2136,11 @@
}
}
+ public static final void doNotUse() {
+ // used by tests to simulate a startup
+ MANAGER = new JavaModelManager();
+ }
+
/*
* Resets the temporary cache for newly created elements to null.
*/
@@ -1954,46 +2211,94 @@
System.out.println(Messages.bind(Messages.build_saveStateComplete, String.valueOf(t)));
}
}
-
+
+ private void saveVariablesAndContainers() throws CoreException {
+ File file = getVariableAndContainersFile();
+ DataOutputStream out = null;
+ try {
+ out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
+ out.writeInt(VARIABLES_AND_CONTAINERS_FILE_VERSION);
+
+ // variables
+ out.writeInt(this.variables.size());
+ Iterator variableNames = this.variables.keySet().iterator();
+ while (variableNames.hasNext()) {
+ String variableName = (String) variableNames.next();
+ out.writeUTF(variableName);
+ IPath path = (IPath) this.variables.get(variableName);
+ out.writeUTF(path == null ? CP_ENTRY_IGNORE : path.toPortableString());
+ }
+
+ // containers
+ IJavaProject[] projects = getJavaModel().getJavaProjects();
+ int length = projects.length;
+ out.writeInt(length);
+ for (int i = 0; i < length; i++) {
+ IJavaProject project = projects[i];
+ // clone while iterating (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59638)
+ Map projectContainers = containerClone(project);
+ out.writeUTF(project.getElementName());
+ if (projectContainers == null) {
+ out.writeInt(0);
+ continue;
+ }
+ HashMap containersToSave = new HashMap();
+ for (Iterator iterator = projectContainers.keySet().iterator(); iterator.hasNext();) {
+ IPath containerPath = (IPath) iterator.next();
+ IClasspathContainer container = (IClasspathContainer) projectContainers.get(containerPath);
+ String containerString = null;
+ try {
+ if (container == null) {
+ // container has not been initialized yet, use previous session value
+ // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=73969)
+ container = getPreviousSessionContainer(containerPath, project);
+ }
+ if (container != null) {
+ IClasspathEntry[] entries = container.getClasspathEntries();
+ containerString = ((JavaProject)project).encodeClasspath(
+ entries,
+ null,
+ false);
+ }
+ } catch(JavaModelException e){
+ // could not encode entry: will not persist
+ Util.log(e, "Could not persist container " + containerPath + " for project " + project.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ if (containerString != null)
+ containersToSave.put(containerPath, containerString);
+ }
+ out.writeInt(containersToSave.size());
+ Iterator iterator = containersToSave.keySet().iterator();
+ while (iterator.hasNext()) {
+ IPath containerPath = (IPath) iterator.next();
+ out.writeUTF(containerPath.toPortableString());
+ String containerString = (String) containersToSave.get(containerPath);
+ out.writeInt(containerString.length());
+ out.writeBytes(containerString);
+ }
+ }
+
+ } catch (IOException e) {
+ IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving variables and containers", e); //$NON-NLS-1$
+ throw new CoreException(status);
+ } finally {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ // nothing we can do: ignore
+ }
+ }
+ }
+ }
+
/**
* @see ISaveParticipant
*/
public void saving(ISaveContext context) throws CoreException {
- // save container values on snapshot/full save
- IJavaProject[] projects = getJavaModel().getJavaProjects();
- IEclipsePreferences preferences = getInstancePreferences();
- for (int i = 0, length = projects.length; i < length; i++) {
- IJavaProject project = projects[i];
- // clone while iterating (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59638)
- Map projectContainers = containerClone(project);
- if (projectContainers == null) continue;
- for (Iterator keys = projectContainers.keySet().iterator(); keys.hasNext();) {
- IPath containerPath = (IPath) keys.next();
- IClasspathContainer container = (IClasspathContainer) projectContainers.get(containerPath);
- String containerKey = CP_CONTAINER_PREFERENCES_PREFIX+project.getElementName() +"|"+containerPath;//$NON-NLS-1$
- String containerString = CP_ENTRY_IGNORE;
- try {
- if (container != null) {
- IClasspathEntry[] entries = container.getClasspathEntries();
- containerString = ((JavaProject)project).encodeClasspath(
- entries,
- null,
- false);
- }
- } catch(JavaModelException e){
- // could not encode entry: leave it as CP_ENTRY_IGNORE
- Util.log(e, "Could not persist container " + containerPath + " for project " + project.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- preferences.put(containerKey, containerString);
- }
- }
- try {
- preferences.flush();
- } catch (BackingStoreException e) {
- IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving context", e); //$NON-NLS-1$
- throw new CoreException(status);
- }
+ // save variable and container values on snapshot/full save
+ saveVariablesAndContainers();
if (context.getKind() == ISaveContext.FULL_SAVE) {
// will need delta since this save (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658)
@@ -2002,7 +2307,10 @@
// clean up indexes on workspace full save
// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=52347)
IndexManager manager = this.indexManager;
- if (manager != null) {
+ if (manager != null
+ // don't force initialization of workspace scope as we could be shutting down
+ // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=93941)
+ && this.workspaceScope != null) {
manager.cleanUpIndexes();
}
}
@@ -2012,18 +2320,27 @@
if (!JavaProject.hasJavaNature(savedProject)) return; // ignore
PerProjectInfo info = getPerProjectInfo(savedProject, true /* create info */);
saveState(info, context);
+ info.rememberExternalLibTimestamps();
return;
}
-
+
ArrayList vStats= null; // lazy initialized
- for (Iterator iter = this.perProjectInfos.values().iterator(); iter.hasNext();) {
- try {
- PerProjectInfo info = (PerProjectInfo) iter.next();
- saveState(info, context);
- } catch (CoreException e) {
- if (vStats == null)
- vStats= new ArrayList();
- vStats.add(e.getStatus());
+ ArrayList values = null;
+ synchronized(this.perProjectInfos) {
+ values = new ArrayList(this.perProjectInfos.values());
+ }
+ if (values != null) {
+ Iterator iterator = values.iterator();
+ while (iterator.hasNext()) {
+ try {
+ PerProjectInfo info = (PerProjectInfo) iterator.next();
+ saveState(info, context);
+ info.rememberExternalLibTimestamps();
+ } catch (CoreException e) {
+ if (vStats == null)
+ vStats= new ArrayList();
+ vStats.add(e.getStatus());
+ }
}
}
if (vStats != null) {
@@ -2031,6 +2348,9 @@
vStats.toArray(stats);
throw new CoreException(new MultiStatus(JavaCore.PLUGIN_ID, IStatus.ERROR, stats, Messages.build_cannotSaveStates, null));
}
+
+ // save external libs timestamps
+ this.deltaState.saveExternalLibTimeStamps();
}
/**
@@ -2108,11 +2428,134 @@
}
}
}
+
+ public void setOptions(Hashtable newOptions) {
+
+ try {
+ IEclipsePreferences defaultPreferences = getDefaultPreferences();
+ IEclipsePreferences instancePreferences = getInstancePreferences();
+
+ if (newOptions == null){
+ instancePreferences.clear();
+ } else {
+ Enumeration keys = newOptions.keys();
+ while (keys.hasMoreElements()){
+ String key = (String)keys.nextElement();
+ if (!this.optionNames.contains(key)) continue; // unrecognized option
+ if (key.equals(JavaCore.CORE_ENCODING)) continue; // skipped, contributed by resource prefs
+ String value = (String)newOptions.get(key);
+ String defaultValue = defaultPreferences.get(key, null);
+ if (defaultValue != null && defaultValue.equals(value)) {
+ instancePreferences.remove(key);
+ } else {
+ instancePreferences.put(key, value);
+ }
+ }
+ }
+
+ // persist options
+ instancePreferences.flush();
+
+ // update cache
+ this.optionsCache = newOptions==null ? null : new Hashtable(newOptions);
+ } catch (BackingStoreException e) {
+ // ignore
+ }
+ }
+
+ public void startup() throws CoreException {
+ try {
+ configurePluginDebugOptions();
+
+ // request state folder creation (workaround 19885)
+ JavaCore.getPlugin().getStateLocation();
+
+ // Initialize eclipse preferences
+ initializePreferences();
+
+ // Listen to preference changes
+ Preferences.IPropertyChangeListener propertyListener = new Preferences.IPropertyChangeListener() {
+ public void propertyChange(Preferences.PropertyChangeEvent event) {
+ JavaModelManager.this.optionsCache = null;
+ }
+ };
+ JavaCore.getPlugin().getPluginPreferences().addPropertyChangeListener(propertyListener);
+
+ // retrieve variable values
+ loadVariablesAndContainers();
+
+ final IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ workspace.addResourceChangeListener(
+ this.deltaState,
+ IResourceChangeEvent.PRE_BUILD
+ | IResourceChangeEvent.POST_BUILD
+ | IResourceChangeEvent.POST_CHANGE
+ | IResourceChangeEvent.PRE_DELETE
+ | IResourceChangeEvent.PRE_CLOSE);
+
+ startIndexing();
+
+ // process deltas since last activated in indexer thread so that indexes are up-to-date.
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658
+ Job processSavedState = new Job(Messages.savedState_jobName) {
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ // add save participant and process delta atomically
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59937
+ workspace.run(
+ new IWorkspaceRunnable() {
+ public void run(IProgressMonitor progress) throws CoreException {
+ ISavedState savedState = workspace.addSaveParticipant(JavaCore.getJavaCore(), JavaModelManager.this);
+ if (savedState != null) {
+ // the event type coming from the saved state is always POST_AUTO_BUILD
+ // force it to be POST_CHANGE so that the delta processor can handle it
+ JavaModelManager.this.deltaState.getDeltaProcessor().overridenEventType = IResourceChangeEvent.POST_CHANGE;
+ savedState.processResourceChangeEvents(JavaModelManager.this.deltaState);
+ }
+ }
+ },
+ monitor);
+ } catch (CoreException e) {
+ return e.getStatus();
+ }
+ return Status.OK_STATUS;
+ }
+ };
+ processSavedState.setSystem(true);
+ processSavedState.setPriority(Job.SHORT); // process asap
+ processSavedState.schedule();
+ } catch (RuntimeException e) {
+ shutdown();
+ throw e;
+ }
+ }
+
+ /**
+ * Initiate the background indexing process.
+ * This should be deferred after the plugin activation.
+ */
+ private void startIndexing() {
+ getIndexManager().reset();
+ }
public void shutdown () {
+ JavaCore javaCore = JavaCore.getJavaCore();
+ javaCore.savePluginPreferences();
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ workspace.removeResourceChangeListener(this.deltaState);
+ workspace.removeSaveParticipant(javaCore);
+
if (this.indexManager != null){ // no more indexing
this.indexManager.shutdown();
}
+
+ // wait for the initialization job to finish
+ try {
+ Platform.getJobManager().join(JavaCore.PLUGIN_ID, null);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+
// Note: no need to close the Java model as this just removes Java element infos from the Java model cache
}
@@ -2327,10 +2770,12 @@
// discard obsoleted information about previous session
this.previousSessionVariables.remove(variableName);
}
-
+
String variableKey = CP_VARIABLE_PREFERENCES_PREFIX+variableName;
- String variableString = variablePath == null ? CP_ENTRY_IGNORE : variablePath.toString();
- getInstancePreferences().put(variableKey, variableString);
+ if (variablePath == null)
+ getInstancePreferences().remove(variableKey);
+ else
+ getInstancePreferences().put(variableKey, variablePath.toString());
try {
getInstancePreferences().flush();
} catch (BackingStoreException e) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index 989536d..a5ea949 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -11,15 +11,6 @@
package org.eclipse.jdt.internal.core;
import java.io.*;
-import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStreamWriter;
-import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -337,8 +328,6 @@
throw newNotPresentException();
}
- IWorkspace workspace = ResourcesPlugin.getWorkspace();
- IWorkspaceRoot wRoot = workspace.getRoot();
// cannot refresh cp markers on opening (emulate cp check on startup) since can create deadlocks (see bug 37274)
IClasspathEntry[] resolvedClasspath = getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
@@ -346,23 +335,11 @@
info.setChildren(computePackageFragmentRoots(resolvedClasspath, false, null /*no reverse map*/));
// remember the timestamps of external libraries the first time they are looked up
- for (int i = 0, length = resolvedClasspath.length; i < length; i++) {
- IClasspathEntry entry = resolvedClasspath[i];
- if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
- IPath path = entry.getPath();
- Object target = JavaModel.getTarget(wRoot, path, true);
- if (target instanceof java.io.File) {
- Map externalTimeStamps = JavaModelManager.getJavaModelManager().deltaState.externalTimeStamps;
- if (externalTimeStamps.get(path) == null) {
- long timestamp = DeltaProcessor.getTimeStamp((java.io.File)target);
- externalTimeStamps.put(path, new Long(timestamp));
- }
- }
- }
- }
+ getPerProjectInfo().rememberExternalLibTimestamps();
return true;
}
+
protected void closing(Object info) {
// forget source attachment recommendations
@@ -550,7 +527,7 @@
root = getPackageFragmentRoot((IResource) target);
} else {
// external target - only JARs allowed
- if (((java.io.File)target).isFile() && (org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(entryPath.lastSegment()))) {
+ if (JavaModel.isFile(target) && (org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(entryPath.lastSegment()))) {
root = new JarPackageFragmentRoot(entryPath, this);
}
}
@@ -863,7 +840,7 @@
if (createMarker && this.project.isAccessible()) {
this.createClasspathProblemMarker(new JavaModelStatus(
IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
- Messages.bind(Messages.classpath_xmlFormatError, (new String[] {this.getElementName(), e.getMessage()}))));
+ Messages.bind(Messages.classpath_xmlFormatError, new String[] {this.getElementName(), e.getMessage()})));
}
if (logProblems) {
Util.log(e,
@@ -876,7 +853,7 @@
if (createMarker && this.project.isAccessible()) {
this.createClasspathProblemMarker(new JavaModelStatus(
IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
- Messages.bind(Messages.classpath_illegalEntryInClasspathFile, (new String[] {this.getElementName(), e.getMessage()}))));
+ Messages.bind(Messages.classpath_illegalEntryInClasspathFile, new String[] {this.getElementName(), e.getMessage()})));
}
if (logProblems) {
Util.log(e,
@@ -928,7 +905,7 @@
try {
ByteArrayOutputStream s = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(s, "UTF8"); //$NON-NLS-1$
- XMLWriter xmlWriter = new XMLWriter(writer);
+ XMLWriter xmlWriter = new XMLWriter(writer, this);
xmlWriter.startTag(ClasspathEntry.TAG_CLASSPATH, indent);
for (int i = 0; i < classpath.length; ++i) {
@@ -1603,7 +1580,7 @@
Iterator propertyNames = projectOptions.keySet().iterator();
while (propertyNames.hasNext()) {
String propertyName = (String) propertyNames.next();
- String propertyValue = (String) perProjectInfo.options.get(propertyName);
+ String propertyValue = (String) projectOptions.get(propertyName);
if (propertyValue != null && optionNames.contains(propertyName)){
options.put(propertyName, propertyValue.trim());
}
@@ -2135,6 +2112,26 @@
// fallback to default
property = new String(bytes);
}
+ } else {
+ // when a project is imported, we get a first delta for the addition of the .project, but the .classpath is not accessible
+ // so default to using java.io.File
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=96258
+ File file = rscFile.getLocation().toFile();
+ if (file.exists()) {
+ byte[] bytes;
+ try {
+ bytes = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(file);
+ } catch (IOException e) {
+ return null;
+ }
+ try {
+ property = new String(bytes, "UTF-8"); //$NON-NLS-1$ // .classpath always encoded with UTF-8
+ } catch (UnsupportedEncodingException e) {
+ Util.log(e, "Could not read .classpath with UTF-8 encoding"); //$NON-NLS-1$
+ // fallback to default
+ property = new String(bytes);
+ }
+ }
}
return property;
}
@@ -2242,41 +2239,102 @@
* @see IJavaProject
*/
public boolean isOnClasspath(IJavaElement element) {
- IPath path = element.getPath();
- IClasspathEntry[] classpath;
+ IClasspathEntry[] rawClasspath;
try {
- classpath = getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
+ rawClasspath = getRawClasspath();
} catch(JavaModelException e){
return false; // not a Java project
}
+ int elementType = element.getElementType();
+ boolean isPackageFragmentRoot = false;
boolean isFolderPath = false;
- switch (element.getElementType()) {
- case IJavaElement.PACKAGE_FRAGMENT_ROOT:
- // package fragment roots must match exactly entry pathes (no exclusion there)
- for (int i = 0; i < classpath.length; i++) {
- IClasspathEntry entry = classpath[i];
- IPath entryPath = entry.getPath();
- if (entryPath.equals(path)) {
- return true;
- }
- }
+ boolean isSource = false;
+ switch (elementType) {
+ case IJavaElement.JAVA_MODEL:
return false;
-
+ case IJavaElement.JAVA_PROJECT:
+ break;
+ case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+ isPackageFragmentRoot = true;
+ break;
case IJavaElement.PACKAGE_FRAGMENT:
- if (!((IPackageFragmentRoot)element.getParent()).isArchive()) {
- // ensure that folders are only excluded if all of their children are excluded
- isFolderPath = true;
- }
+ isFolderPath = !((IPackageFragmentRoot)element.getParent()).isArchive();
+ break;
+ case IJavaElement.COMPILATION_UNIT:
+ isSource = true;
+ break;
+ default:
+ isSource = element.getAncestor(IJavaElement.COMPILATION_UNIT) != null;
break;
}
- for (int i = 0; i < classpath.length; i++) {
- IClasspathEntry entry = classpath[i];
- IPath entryPath = entry.getPath();
- if (entryPath.isPrefixOf(path)
- && !Util.isExcluded(path, ((ClasspathEntry)entry).fullInclusionPatternChars(), ((ClasspathEntry)entry).fullExclusionPatternChars(), isFolderPath)) {
- return true;
+ IPath elementPath = element.getPath();
+
+ // first look at unresolved entries
+ int length = rawClasspath.length;
+ for (int i = 0; i < length; i++) {
+ IClasspathEntry entry = rawClasspath[i];
+ switch (entry.getEntryKind()) {
+ case IClasspathEntry.CPE_LIBRARY:
+ case IClasspathEntry.CPE_PROJECT:
+ case IClasspathEntry.CPE_SOURCE:
+ if (isOnClasspathEntry(elementPath, isFolderPath, isPackageFragmentRoot, entry))
+ return true;
+ break;
}
}
+
+ // no need to go further for compilation units and elements inside a compilation unit
+ // it can only be in a source folder, thus on the raw classpath
+ if (isSource)
+ return false;
+
+ // then look at resolved entries
+ for (int i = 0; i < length; i++) {
+ IClasspathEntry rawEntry = rawClasspath[i];
+ switch (rawEntry.getEntryKind()) {
+ case IClasspathEntry.CPE_CONTAINER:
+ IClasspathContainer container;
+ try {
+ container = JavaCore.getClasspathContainer(rawEntry.getPath(), this);
+ } catch (JavaModelException e) {
+ break;
+ }
+ if (container == null)
+ break;
+ IClasspathEntry[] containerEntries = container.getClasspathEntries();
+ if (containerEntries == null)
+ break;
+ // container was bound
+ for (int j = 0, containerLength = containerEntries.length; j < containerLength; j++){
+ IClasspathEntry resolvedEntry = containerEntries[j];
+ if (isOnClasspathEntry(elementPath, isFolderPath, isPackageFragmentRoot, resolvedEntry))
+ return true;
+ }
+ break;
+ case IClasspathEntry.CPE_VARIABLE:
+ IClasspathEntry resolvedEntry = JavaCore.getResolvedClasspathEntry(rawEntry);
+ if (resolvedEntry == null)
+ break;
+ if (isOnClasspathEntry(elementPath, isFolderPath, isPackageFragmentRoot, resolvedEntry))
+ return true;
+ break;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean isOnClasspathEntry(IPath elementPath, boolean isFolderPath, boolean isPackageFragmentRoot, IClasspathEntry entry) {
+ IPath entryPath = entry.getPath();
+ if (isPackageFragmentRoot) {
+ // package fragment roots must match exactly entry pathes (no exclusion there)
+ if (entryPath.equals(elementPath))
+ return true;
+ } else {
+ if (entryPath.isPrefixOf(elementPath)
+ && !Util.isExcluded(elementPath, ((ClasspathEntry)entry).fullInclusionPatternChars(), ((ClasspathEntry)entry).fullExclusionPatternChars(), isFolderPath))
+ return true;
+ }
return false;
}
@@ -2349,8 +2407,9 @@
* @see IJavaProject#newEvaluationContext()
*/
public IEvaluationContext newEvaluationContext() {
-
- return new EvaluationContextWrapper(new EvaluationContext(), this);
+ EvaluationContext context = new EvaluationContext();
+ context.setLineSeparator(Util.getLineSeparator(null/*no existing source*/, this));
+ return new EvaluationContextWrapper(context, this);
}
/*
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
index b7cd37e..c70d140 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
@@ -180,7 +180,7 @@
return true;
}
- protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+ protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
if (info != NO_INFO) {
buffer.append(Signature.toString(this.getTypeSignature()));
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
index 504a766..da25a32 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
@@ -124,11 +124,13 @@
public long timeSpentInSeekTypesInBinaryPackage = 0;
public NameLookup(IPackageFragmentRoot[] packageFragmentRoots, HashtableOfArrayToObject packageFragments, ICompilationUnit[] workingCopies, Map rootToResolvedEntries) {
+ long start = -1;
if (VERBOSE) {
System.out.println(Thread.currentThread() + " BUILDING NameLoopkup"); //$NON-NLS-1$
System.out.println(Thread.currentThread() + " -> pkg roots size: " + (packageFragmentRoots == null ? 0 : packageFragmentRoots.length)); //$NON-NLS-1$
System.out.println(Thread.currentThread() + " -> pkgs size: " + (packageFragments == null ? 0 : packageFragments.size())); //$NON-NLS-1$
System.out.println(Thread.currentThread() + " -> working copy size: " + (workingCopies == null ? 0 : workingCopies.length)); //$NON-NLS-1$
+ start = System.currentTimeMillis();
}
this.packageFragmentRoots = packageFragmentRoots;
try {
@@ -138,7 +140,6 @@
}
if (workingCopies != null) {
this.unitsToLookInside = new HashMap();
- HashSet visited = new HashSet();
for (int i = 0, length = workingCopies.length; i < length; i++) {
ICompilationUnit workingCopy = workingCopies[i];
PackageFragment pkg = (PackageFragment) workingCopy.getParent();
@@ -171,26 +172,37 @@
// add root of package fragment to cache
IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent();
- if (visited.contains(root)) continue;
String[] pkgName = pkg.names;
Object existing = this.packageFragments.get(pkgName);
if (existing == null) {
this.packageFragments.put(pkgName, root);
} else {
if (existing instanceof PackageFragmentRoot) {
- this.packageFragments.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
+ if (!existing.equals(root))
+ this.packageFragments.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
} else {
IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing;
int rootLength = roots.length;
- System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength);
- roots[rootLength] = root;
- this.packageFragments.put(pkgName, roots);
+ boolean containsRoot = false;
+ for (int j = 0; j < rootLength; j++) {
+ if (roots[j].equals(root)) {
+ containsRoot = true;
+ break;
+ }
+ }
+ if (containsRoot) {
+ System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength);
+ roots[rootLength] = root;
+ this.packageFragments.put(pkgName, roots);
+ }
}
}
- visited.add(root);
}
}
this.rootToResolvedEntries = rootToResolvedEntries;
+ if (VERBOSE) {
+ System.out.println(Thread.currentThread() + " -> spent: " + (start - System.currentTimeMillis()) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
/**
@@ -757,6 +769,7 @@
seekTypesInBinaryPackage(matchName, pkg, partialMatch, acceptFlags, requestor);
break;
case IPackageFragmentRoot.K_SOURCE :
+ matchName= matchName.replace('$', '.');
seekTypesInSourcePackage(matchName, pkg, partialMatch, acceptFlags, requestor);
break;
default :
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java
index f7a44dd..1de6701 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java
@@ -11,7 +11,6 @@
package org.eclipse.jdt.internal.core;
import org.eclipse.jdt.core.BindingKey;
-import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
@@ -64,34 +63,25 @@
return this.name;
}
- protected String getKey(IField field, boolean withAccessFlags, boolean forceOpen) throws JavaModelException {
+ protected String getKey(IField field, boolean forceOpen) throws JavaModelException {
StringBuffer key = new StringBuffer();
// declaring class
- String declaringKey = getKey((IType) field.getParent(), false/*without access flags*/, forceOpen);
+ String declaringKey = getKey((IType) field.getParent(), forceOpen);
key.append(declaringKey);
// field name
key.append('.');
key.append(field.getElementName());
-
- // flags
- if (withAccessFlags) {
- key.append('^');
- if (forceOpen)
- key.append(field.getFlags());
- else
- key.append(Flags.AccDefault);
- }
return key.toString();
}
- protected String getKey(IMethod method, boolean withAccessFlags, boolean forceOpen) throws JavaModelException {
+ protected String getKey(IMethod method, boolean forceOpen) throws JavaModelException {
StringBuffer key = new StringBuffer();
// declaring class
- String declaringKey = getKey((IType) method.getParent(), false/*without access flags*/, forceOpen);
+ String declaringKey = getKey((IType) method.getParent(), forceOpen);
key.append(declaringKey);
// selector
@@ -112,19 +102,10 @@
else
key.append('V');
- // flags
- if (withAccessFlags) {
- key.append('^');
- if (forceOpen)
- key.append(method.getFlags());
- else
- key.append(Flags.AccDefault); // cannot get the flags without opening the element
- }
-
return key.toString();
}
- protected String getKey(IType type, boolean withAccessFlags, boolean forceOpen) throws JavaModelException {
+ protected String getKey(IType type, boolean forceOpen) throws JavaModelException {
StringBuffer key = new StringBuffer();
key.append('L');
String packageName = type.getPackageFragment().getElementName();
@@ -147,13 +128,6 @@
}
key.append(typeQualifiedName);
key.append(';');
- if (withAccessFlags) {
- key.append('^');
- if (forceOpen)
- key.append(type.getFlags());
- else
- key.append(Flags.AccDefault);
- }
return key.toString();
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java
index 1172955..4d31c65 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java
@@ -55,7 +55,7 @@
/**
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
buffer.append("package "); //$NON-NLS-1$
toStringName(buffer);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
index 62ad20b..f2065fa 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
@@ -415,7 +415,7 @@
/**
* Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
if (this.names.length == 0) {
buffer.append("<default>"); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
index e9dda69..0896050 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -374,8 +374,8 @@
return entry;
}
} else if (target instanceof java.io.File){
- java.io.File file = (java.io.File) target;
- if (file.isFile()) {
+ java.io.File file = JavaModel.getFile(target);
+ if (file != null) {
if (org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(file.getName())){
return entry;
}
@@ -820,12 +820,12 @@
/**
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
IPath path = getPath();
if (getJavaProject().getElementName().equals(path.segment(0))) {
if (path.segmentCount() == 1) {
- buffer.append("<project root>"); //$NON-NLS-1$
+ buffer.append("<project root>"); //$NON-NLS-1$
} else {
buffer.append(path.removeFirstSegments(1).makeRelative());
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java
index fb01686..3e24250 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java
@@ -43,10 +43,12 @@
/**
* @private Debugging purposes
*/
- protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
- super.toStringInfo(tab, buffer, info);
- buffer.append(" {key="); //$NON-NLS-1$
- buffer.append(this.uniqueKey);
- buffer.append("}"); //$NON-NLS-1$
+ protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+ super.toStringInfo(tab, buffer, info, showResolvedInfo);
+ if (showResolvedInfo) {
+ buffer.append(" {key="); //$NON-NLS-1$
+ buffer.append(this.uniqueKey);
+ buffer.append("}"); //$NON-NLS-1$
+ }
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java
index 3014dc9..5c68ee4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java
@@ -40,10 +40,12 @@
/**
* @private Debugging purposes
*/
- protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
- super.toStringInfo(tab, buffer, info);
- buffer.append(" {key="); //$NON-NLS-1$
- buffer.append(this.uniqueKey);
- buffer.append("}"); //$NON-NLS-1$
+ protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+ super.toStringInfo(tab, buffer, info, showResolvedInfo);
+ if (showResolvedInfo) {
+ buffer.append(" {key="); //$NON-NLS-1$
+ buffer.append(this.uniqueKey);
+ buffer.append("}"); //$NON-NLS-1$
+ }
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java
index 7f31640..90b3553 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java
@@ -49,10 +49,12 @@
/**
* @private Debugging purposes
*/
- protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
- super.toStringInfo(tab, buffer, info);
- buffer.append(" {key="); //$NON-NLS-1$
- buffer.append(this.uniqueKey);
- buffer.append("}"); //$NON-NLS-1$
+ protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+ super.toStringInfo(tab, buffer, info, showResolvedInfo);
+ if (showResolvedInfo) {
+ buffer.append(" {key="); //$NON-NLS-1$
+ buffer.append(this.uniqueKey);
+ buffer.append("}"); //$NON-NLS-1$
+ }
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceField.java
index 0c027fd..ec7e24d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceField.java
@@ -43,10 +43,12 @@
/**
* @private Debugging purposes
*/
- protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
- super.toStringInfo(tab, buffer, info);
- buffer.append(" {key="); //$NON-NLS-1$
- buffer.append(this.uniqueKey);
- buffer.append("}"); //$NON-NLS-1$
+ protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+ super.toStringInfo(tab, buffer, info, showResolvedInfo);
+ if (showResolvedInfo) {
+ buffer.append(" {key="); //$NON-NLS-1$
+ buffer.append(this.uniqueKey);
+ buffer.append("}"); //$NON-NLS-1$
+ }
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceMethod.java
index c9d8e45..3ba8dba 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceMethod.java
@@ -41,10 +41,12 @@
/**
* @private Debugging purposes
*/
- protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
- super.toStringInfo(tab, buffer, info);
- buffer.append(" {key="); //$NON-NLS-1$
- buffer.append(this.uniqueKey);
- buffer.append("}"); //$NON-NLS-1$
+ protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+ super.toStringInfo(tab, buffer, info, showResolvedInfo);
+ if (showResolvedInfo) {
+ buffer.append(" {key="); //$NON-NLS-1$
+ buffer.append(this.uniqueKey);
+ buffer.append("}"); //$NON-NLS-1$
+ }
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java
index 9d2f0a3..b61905c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java
@@ -49,10 +49,12 @@
/**
* @private Debugging purposes
*/
- protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
- super.toStringInfo(tab, buffer, info);
- buffer.append(" {key="); //$NON-NLS-1$
- buffer.append(this.uniqueKey);
- buffer.append("}"); //$NON-NLS-1$
+ protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
+ super.toStringInfo(tab, buffer, info, showResolvedInfo);
+ if (showResolvedInfo) {
+ buffer.append(" {key="); //$NON-NLS-1$
+ buffer.append(this.uniqueKey);
+ buffer.append("}"); //$NON-NLS-1$
+ }
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
index 6dab364..4da06fa 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
@@ -101,7 +101,7 @@
if (accessRuleSet != null) {
// TODO (philippe) improve char[] <-> String conversions to avoid performing them on the fly
char[][] packageChars = CharOperation.splitOn('.', packageName.toCharArray());
- char[] classFileChars = type.getParent().getElementName().toCharArray();
+ char[] classFileChars = type.getElementName().toCharArray();
accessRestriction = accessRuleSet.getViolatedRestriction(CharOperation.concatWith(packageChars, classFileChars, '/'));
}
}
@@ -205,7 +205,7 @@
* This method can not be used to find member types... member
* types are found relative to their enclosing type.
*/
- public void findTypes(char[] prefix, final ISearchRequestor storage) {
+ public void findTypes(char[] prefix, final boolean findMembers, final ISearchRequestor storage) {
/*
if (true){
@@ -271,9 +271,9 @@
public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
if (excludePath != null && excludePath.equals(path))
return;
- if (enclosingTypeNames != null && enclosingTypeNames.length > 0)
+ if (!findMembers && enclosingTypeNames != null && enclosingTypeNames.length > 0)
return; // accept only top level types
- storage.acceptType(packageName, simpleTypeName, modifiers, access);
+ storage.acceptType(packageName, simpleTypeName, enclosingTypeNames, modifiers, access);
}
};
try {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java
index 0346a12..5800cce 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java
@@ -107,12 +107,12 @@
if (accessRuleSet != null) {
// TODO (philippe) improve char[] <-> String conversions to avoid performing them on the fly
char[][] packageChars = CharOperation.splitOn('.', packageName);
- char[] fileChars = type.getParent().getElementName().toCharArray();
- accessRestriction = accessRuleSet.getViolatedRestriction(CharOperation.concatWith(packageChars, fileChars, '/'));
+ char[] fileWithoutExtension = type.getElementName().toCharArray();
+ accessRestriction = accessRuleSet.getViolatedRestriction(CharOperation.concatWith(packageChars, fileWithoutExtension, '/'));
}
}
}
- this.requestor.acceptType(packageName, type.getElementName().toCharArray(), type.getFlags(), accessRestriction);
+ this.requestor.acceptType(packageName, type.getElementName().toCharArray(), null, type.getFlags(), accessRestriction);
} catch (JavaModelException jme) {
// ignore
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java
index 153d2e2..53e7c13 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java
@@ -13,6 +13,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Iterator;
import java.util.List;
import org.eclipse.jdt.core.IBuffer;
@@ -26,12 +27,16 @@
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
+import org.eclipse.jdt.core.util.CompilationUnitSorter;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jface.text.BadLocationException;
@@ -49,17 +54,21 @@
Comparator comparator;
int[] positions;
+ int apiLevel;
/**
* Constructor for SortElementsOperation.
+ *
+ * @param level the AST API level; one of the AST LEVEL constants
* @param elements
* @param positions
* @param comparator
*/
- public SortElementsOperation(IJavaElement[] elements, int[] positions, Comparator comparator) {
+ public SortElementsOperation(int level, IJavaElement[] elements, int[] positions, Comparator comparator) {
super(elements);
this.comparator = comparator;
- this.positions = positions;
+ this.positions = positions;
+ this.apiLevel = level;
}
/**
@@ -100,12 +109,62 @@
*/
private String processElement(ICompilationUnit unit, char[] source) {
CompilerOptions options = new CompilerOptions(unit.getJavaProject().getOptions(true));
- ASTParser parser = ASTParser.newParser(AST.JLS3);
+ ASTParser parser = ASTParser.newParser(this.apiLevel);
parser.setCompilerOptions(options.getMap());
parser.setSource(source);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setResolveBindings(false);
org.eclipse.jdt.core.dom.CompilationUnit domUnit = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(null);
+ domUnit.accept(new ASTVisitor() {
+ public boolean visit(org.eclipse.jdt.core.dom.CompilationUnit compilationUnit) {
+ List types = compilationUnit.types();
+ for (Iterator iter = types.iterator(); iter.hasNext();) {
+ AbstractTypeDeclaration typeDeclaration = (AbstractTypeDeclaration) iter.next();
+ typeDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(typeDeclaration.getStartPosition()));
+ }
+ return true;
+ }
+ public boolean visit(AnnotationTypeDeclaration annotationTypeDeclaration) {
+ List bodyDeclarations = annotationTypeDeclaration.bodyDeclarations();
+ for (Iterator iter = bodyDeclarations.iterator(); iter.hasNext();) {
+ BodyDeclaration bodyDeclaration = (BodyDeclaration) iter.next();
+ bodyDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(bodyDeclaration.getStartPosition()));
+ }
+ return true;
+ }
+
+ public boolean visit(AnonymousClassDeclaration anonymousClassDeclaration) {
+ List bodyDeclarations = anonymousClassDeclaration.bodyDeclarations();
+ for (Iterator iter = bodyDeclarations.iterator(); iter.hasNext();) {
+ BodyDeclaration bodyDeclaration = (BodyDeclaration) iter.next();
+ bodyDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(bodyDeclaration.getStartPosition()));
+ }
+ return true;
+ }
+
+ public boolean visit(TypeDeclaration typeDeclaration) {
+ List bodyDeclarations = typeDeclaration.bodyDeclarations();
+ for (Iterator iter = bodyDeclarations.iterator(); iter.hasNext();) {
+ BodyDeclaration bodyDeclaration = (BodyDeclaration) iter.next();
+ bodyDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(bodyDeclaration.getStartPosition()));
+ }
+ return true;
+ }
+
+ public boolean visit(EnumDeclaration enumDeclaration) {
+ List bodyDeclarations = enumDeclaration.bodyDeclarations();
+ for (Iterator iter = bodyDeclarations.iterator(); iter.hasNext();) {
+ BodyDeclaration bodyDeclaration = (BodyDeclaration) iter.next();
+ bodyDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(bodyDeclaration.getStartPosition()));
+ }
+ List enumConstants = enumDeclaration.enumConstants();
+ for (Iterator iter = enumConstants.iterator(); iter.hasNext();) {
+ EnumConstantDeclaration enumConstantDeclaration = (EnumConstantDeclaration) iter.next();
+ enumConstantDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(enumConstantDeclaration.getStartPosition()));
+ }
+ return true;
+ }
+ });
final AST localAst = domUnit.getAST();
final ASTRewrite rewriter = ASTRewrite.create(localAst);
RangeMarker[] markers = null;
@@ -190,7 +249,7 @@
for (int i = 0; i < length; i++) {
listRewrite.replace((ASTNode) bodyDeclarations.get(i), rewriter.createMoveTarget((ASTNode) myCopy.get(i)), null);
}
- }
+ }
listRewrite = rewriter.getListRewrite(enumDeclaration, EnumDeclaration.ENUM_CONSTANTS_PROPERTY);
List enumConstants = enumDeclaration.enumConstants();
length = enumConstants.size();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java
index 33af54e..dc936e7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java
@@ -98,7 +98,7 @@
*/
public String getKey() {
try {
- return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, false/*don't open*/);
+ return getKey(this, false/*don't open*/);
} catch (JavaModelException e) {
// happen only if force open is true
return null;
@@ -147,7 +147,7 @@
/**
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(this.tabString(tab));
if (info == null) {
toStringName(buffer);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
index 23bf465..23fdcae 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
@@ -13,11 +13,15 @@
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -36,6 +40,7 @@
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
@@ -78,7 +83,7 @@
* the zip (empty specifies the default root). <code>null</code> is
* not a valid root path.
*/
- protected HashSet rootPaths;
+ protected ArrayList rootPaths;
/**
* The binary type source is being mapped for
@@ -94,7 +99,7 @@
* the zip (empty specifies the default root). <code>null</code> is
* not a valid root path.
*/
- protected String rootPath;
+ protected String rootPath = ""; //$NON-NLS-1$
/**
* Used for efficiency
@@ -199,7 +204,7 @@
// use no encoding
}
if (rootPath != null) {
- this.rootPaths = new HashSet();
+ this.rootPaths = new ArrayList();
this.rootPaths.add(rootPath);
}
this.sourcePath = sourcePath;
@@ -306,9 +311,7 @@
}
private void computeAllRootPaths(IPackageFragmentRoot root) {
- if (this.rootPaths == null) {
- this.rootPaths = new HashSet();
- }
+ final HashSet tempRoots = new HashSet();
long time = 0;
if (VERBOSE) {
System.out.println("compute all root paths for " + root.getElementName()); //$NON-NLS-1$
@@ -330,9 +333,11 @@
int index = entryName.indexOf('/');
if (index != -1 && Util.isClassFileName(entryName)) {
String firstLevelPackageName = entryName.substring(0, index);
- IStatus status = JavaConventions.validatePackageName(firstLevelPackageName);
- if (status.isOK() || status.getSeverity() == IStatus.WARNING) {
- firstLevelPackageNames.add(firstLevelPackageName);
+ if (!firstLevelPackageNames.contains(firstLevelPackageName)) {
+ IStatus status = JavaConventions.validatePackageName(firstLevelPackageName);
+ if (status.isOK() || status.getSeverity() == IStatus.WARNING) {
+ firstLevelPackageNames.add(firstLevelPackageName);
+ }
}
} else if (Util.isClassFileName(entryName)) {
containsADefaultPackage = true;
@@ -393,15 +398,15 @@
if (segmentCount > 1) {
loop: for (int i = 0, max = path.segmentCount() - 1; i < max; i++) {
if (firstLevelPackageNames.contains(path.segment(i))) {
- this.rootPaths.add(path.uptoSegment(i).toString());
+ tempRoots.add(path.uptoSegment(i));
// don't break here as this path could contain other first level package names (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=74014)
}
if (i == max - 1 && containsADefaultPackage) {
- this.rootPaths.add(path.uptoSegment(max).toString());
+ tempRoots.add(path.uptoSegment(max));
}
}
} else if (containsADefaultPackage) {
- this.rootPaths.add(""); //$NON-NLS-1$
+ tempRoots.add(new Path("")); //$NON-NLS-1$
}
}
}
@@ -414,23 +419,54 @@
Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), this.sourcePath, true);
if (target instanceof IResource) {
if (target instanceof IContainer) {
- computeRootPath((IContainer)target, firstLevelPackageNames, containsADefaultPackage);
+ computeRootPath((IContainer)target, firstLevelPackageNames, containsADefaultPackage, tempRoots);
}
} else if (target instanceof File) {
File file = (File)target;
if (file.isDirectory()) {
- computeRootPath(file, firstLevelPackageNames, containsADefaultPackage);
+ computeRootPath(file, firstLevelPackageNames, containsADefaultPackage, tempRoots);
}
}
}
- if (VERBOSE) {
- System.out.println("Found " + this.rootPaths.size() + " root paths"); //$NON-NLS-1$ //$NON-NLS-2$
- System.out.println("Spent " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ int size = tempRoots.size();
+ if (this.rootPaths != null) {
+ for (Iterator iterator = this.rootPaths.iterator(); iterator.hasNext(); ) {
+ tempRoots.add(new Path((String) iterator.next()));
+ }
+ this.rootPaths.clear();
+ } else {
+ this.rootPaths = new ArrayList(size);
+ }
+ size = tempRoots.size();
+ if (size > 0) {
+ ArrayList sortedRoots = new ArrayList(tempRoots);
+ if (size > 1) {
+ Collections.sort(sortedRoots, new Comparator() {
+ public int compare(Object o1, Object o2) {
+ IPath path1 = (IPath) o1;
+ IPath path2 = (IPath) o2;
+ return path1.segmentCount() - path2.segmentCount();
+ }
+ });
+ }
+ for (Iterator iter = sortedRoots.iterator(); iter.hasNext();) {
+ IPath path = (IPath) iter.next();
+ this.rootPaths.add(path.toString());
+ }
}
this.areRootPathsComputed = true;
+ if (VERBOSE) {
+ System.out.println("Spent " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
+ System.out.println("Found " + size + " root paths"); //$NON-NLS-1$ //$NON-NLS-2$
+ int i = 0;
+ for (Iterator iterator = this.rootPaths.iterator(); iterator.hasNext();) {
+ System.out.println("root[" + i + "]=" + ((String) iterator.next()));//$NON-NLS-1$ //$NON-NLS-2$
+ i++;
+ }
+ }
}
- private void computeRootPath(File directory, HashSet firstLevelPackageNames, boolean hasDefaultPackage) {
+ private void computeRootPath(File directory, HashSet firstLevelPackageNames, boolean hasDefaultPackage, Set set) {
File[] files = directory.listFiles();
boolean hasSubDirectories = false;
loop: for (int i = 0, max = files.length; i < max; i++) {
@@ -440,23 +476,23 @@
if (firstLevelPackageNames.contains(file.getName())) {
IPath fullPath = new Path(file.getParentFile().getPath());
IPath rootPathEntry = fullPath.removeFirstSegments(this.sourcePath.segmentCount()).setDevice(null);
- this.rootPaths.add(rootPathEntry.toString());
+ set.add(rootPathEntry);
break loop;
} else {
- computeRootPath(file, firstLevelPackageNames, hasDefaultPackage);
+ computeRootPath(file, firstLevelPackageNames, hasDefaultPackage, set);
}
} else if (i == max - 1 && !hasSubDirectories && hasDefaultPackage) {
File parentDir = file.getParentFile();
if (parentDir.list(FILENAME_FILTER).length != 0) {
IPath fullPath = new Path(parentDir.getPath());
IPath rootPathEntry = fullPath.removeFirstSegments(this.sourcePath.segmentCount()).setDevice(null);
- this.rootPaths.add(rootPathEntry.toString());
+ set.add(rootPathEntry);
}
}
}
}
- private void computeRootPath(IContainer container, HashSet firstLevelPackageNames, boolean hasDefaultPackage) {
+ private void computeRootPath(IContainer container, HashSet firstLevelPackageNames, boolean hasDefaultPackage, Set set) {
try {
IResource[] resources = container.members();
boolean hasSubDirectories = false;
@@ -467,10 +503,10 @@
if (firstLevelPackageNames.contains(resource.getName())) {
IPath fullPath = container.getFullPath();
IPath rootPathEntry = fullPath.removeFirstSegments(this.sourcePath.segmentCount()).setDevice(null);
- this.rootPaths.add(rootPathEntry.toString());
+ set.add(rootPathEntry);
break loop;
} else {
- computeRootPath((IFolder) resource, firstLevelPackageNames, hasDefaultPackage);
+ computeRootPath((IFolder) resource, firstLevelPackageNames, hasDefaultPackage, set);
}
}
if (i == max - 1 && !hasSubDirectories && hasDefaultPackage) {
@@ -485,7 +521,7 @@
if (hasJavaSourceFile) {
IPath fullPath = container.getFullPath();
IPath rootPathEntry = fullPath.removeFirstSegments(this.sourcePath.segmentCount()).setDevice(null);
- this.rootPaths.add(rootPathEntry.toString());
+ set.add(rootPathEntry);
}
}
}
@@ -563,8 +599,24 @@
this.typeNameRanges[typeDepth] =
new SourceRange(typeInfo.nameSourceStart, typeInfo.nameSourceEnd - typeInfo.nameSourceStart + 1);
this.typeDeclarationStarts[typeDepth] = typeInfo.declarationStart;
+
+ if (typeInfo.typeParameters != null) {
+ final IType currentType = this.types[typeDepth];
+ for (int i = 0, length = typeInfo.typeParameters.length; i < length; i++) {
+ final TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i];
+ final ITypeParameter typeParameter = currentType.getTypeParameter(new String(typeParameterInfo.name));
+ setSourceRange(
+ typeParameter,
+ new SourceRange(
+ typeParameterInfo.declarationStart,
+ typeParameterInfo.declarationEnd - typeParameterInfo.declarationStart + 1),
+ new SourceRange(
+ typeParameterInfo.nameSourceStart,
+ typeParameterInfo.nameSourceEnd - typeParameterInfo.nameSourceStart + 1));
+ }
+ }
}
-
+
/**
* @see ISourceElementRequestor
*/
@@ -613,7 +665,28 @@
new SourceRange(methodInfo.nameSourceStart, methodInfo.nameSourceEnd - methodInfo.nameSourceStart + 1);
fMemberDeclarationStart[typeDepth] = methodInfo.declarationStart;
fMethodParameterTypes[typeDepth] = methodInfo.parameterTypes;
- fMethodParameterNames[typeDepth] =methodInfo. parameterNames;
+ fMethodParameterNames[typeDepth] = methodInfo. parameterNames;
+
+ if (methodInfo.typeParameters != null) {
+ final IType currentType = this.types[typeDepth];
+ IMethod method = currentType.getMethod(
+ fMemberName[typeDepth],
+ convertTypeNamesToSigs(fMethodParameterTypes[typeDepth]));
+ if (method == null) return;
+
+ for (int i = 0, length = methodInfo.typeParameters.length; i < length; i++) {
+ final TypeParameterInfo typeParameterInfo = methodInfo.typeParameters[i];
+ final ITypeParameter typeParameter = method.getTypeParameter(new String(typeParameterInfo.name));
+ setSourceRange(
+ typeParameter,
+ new SourceRange(
+ typeParameterInfo.declarationStart,
+ typeParameterInfo.declarationEnd - typeParameterInfo.declarationStart + 1),
+ new SourceRange(
+ typeParameterInfo.nameSourceStart,
+ typeParameterInfo.nameSourceEnd - typeParameterInfo.nameSourceStart + 1));
+ }
+ }
}
}
@@ -740,15 +813,14 @@
char[] source = null;
- if (!areRootPathsComputed) {
- computeAllRootPaths((IPackageFragmentRoot) type.getPackageFragment().getParent());
- }
-
if (this.rootPath != null) {
source = getSourceForRootPath(this.rootPath, name);
}
if (source == null) {
+ if (!areRootPathsComputed) {
+ computeAllRootPaths((IPackageFragmentRoot) type.getPackageFragment().getParent());
+ }
/*
* We should try all existing root paths. If none works, try to recompute it.
* If it still doesn't work, then return null
@@ -843,14 +915,31 @@
* {-1, -1} if no source range is known for the name of the element.
*/
public SourceRange getNameRange(IJavaElement element) {
- if (element.getElementType() == IJavaElement.METHOD
- && ((IMember) element).isBinary()) {
- IJavaElement[] el = getUnqualifiedMethodHandle((IMethod) element, false);
- if(el[1] != null && fSourceRanges.get(el[0]) == null) {
- element = getUnqualifiedMethodHandle((IMethod) element, true)[0];
- } else {
- element = el[0];
- }
+ switch(element.getElementType()) {
+ case IJavaElement.METHOD :
+ if (((IMember) element).isBinary()) {
+ IJavaElement[] el = getUnqualifiedMethodHandle((IMethod) element, false);
+ if(el[1] != null && fSourceRanges.get(el[0]) == null) {
+ element = getUnqualifiedMethodHandle((IMethod) element, true)[0];
+ } else {
+ element = el[0];
+ }
+ }
+ break;
+ case IJavaElement.TYPE_PARAMETER :
+ IJavaElement parent = element.getParent();
+ if (parent.getElementType() == IJavaElement.METHOD) {
+ IMethod method = (IMethod) parent;
+ if (method.isBinary()) {
+ IJavaElement[] el = getUnqualifiedMethodHandle(method, false);
+ if(el[1] != null && fSourceRanges.get(el[0]) == null) {
+ method = (IMethod) getUnqualifiedMethodHandle(method, true)[0];
+ } else {
+ method = (IMethod) el[0];
+ }
+ element = method.getTypeParameter(element.getElementName());
+ }
+ }
}
SourceRange[] ranges = (SourceRange[]) fSourceRanges.get(element);
if (ranges == null) {
@@ -886,14 +975,31 @@
* {-1, -1} if no source range is known for the element.
*/
public SourceRange getSourceRange(IJavaElement element) {
- if (element.getElementType() == IJavaElement.METHOD
- && ((IMember) element).isBinary()) {
- IJavaElement[] el = getUnqualifiedMethodHandle((IMethod) element, false);
- if(el[1] != null && fSourceRanges.get(el[0]) == null) {
- element = getUnqualifiedMethodHandle((IMethod) element, true)[0];
- } else {
- element = el[0];
- }
+ switch(element.getElementType()) {
+ case IJavaElement.METHOD :
+ if (((IMember) element).isBinary()) {
+ IJavaElement[] el = getUnqualifiedMethodHandle((IMethod) element, false);
+ if(el[1] != null && fSourceRanges.get(el[0]) == null) {
+ element = getUnqualifiedMethodHandle((IMethod) element, true)[0];
+ } else {
+ element = el[0];
+ }
+ }
+ break;
+ case IJavaElement.TYPE_PARAMETER :
+ IJavaElement parent = element.getParent();
+ if (parent.getElementType() == IJavaElement.METHOD) {
+ IMethod method = (IMethod) parent;
+ if (method.isBinary()) {
+ IJavaElement[] el = getUnqualifiedMethodHandle(method, false);
+ if(el[1] != null && fSourceRanges.get(el[0]) == null) {
+ method = (IMethod) getUnqualifiedMethodHandle(method, true)[0];
+ } else {
+ method = (IMethod) el[0];
+ }
+ element = method.getTypeParameter(element.getElementName());
+ }
+ }
}
SourceRange[] ranges = (SourceRange[]) fSourceRanges.get(element);
if (ranges == null) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java
index 2730f34..e337487 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java
@@ -96,7 +96,7 @@
*/
public String getKey() {
try {
- return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, false/*don't open*/);
+ return getKey(this, false/*don't open*/);
} catch (JavaModelException e) {
// happen only if force open is true
return null;
@@ -250,7 +250,7 @@
/**
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(tabString(tab));
if (info == null) {
toStringName(buffer);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
index 4f72a4d..ff40087 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
@@ -336,7 +336,7 @@
*/
public String getKey() {
try {
- return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, false/*don't open*/);
+ return getKey(this, false/*don't open*/);
} catch (JavaModelException e) {
// happen only if force open is true
return null;
@@ -832,7 +832,7 @@
/**
* @private Debugging purposes
*/
-protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) {
buffer.append(tabString(tab));
if (info == null) {
String elementName = getElementName();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java
index a1b861e..a3361a6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java
@@ -58,6 +58,26 @@
return new SourceRange(info.nameStart, info.nameEnd - info.nameStart + 1);
}
+ /*
+ * @see ISourceReference
+ */
+ public ISourceRange getSourceRange() throws JavaModelException {
+ SourceMapper mapper= getSourceMapper();
+ if (mapper != null) {
+ // ensure the class file's buffer is open so that source ranges are computed
+ ClassFile classFile = (ClassFile)getClassFile();
+ if (classFile != null) {
+ classFile.getBuffer();
+ return mapper.getSourceRange(this);
+ }
+ }
+ return super.getSourceRange();
+ }
+
+ public IClassFile getClassFile() {
+ return ((JavaElement)getParent()).getClassFile();
+ }
+
protected void toStringName(StringBuffer buffer) {
buffer.append('<');
buffer.append(getElementName());
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java
index 481781c..14c3a78 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java
@@ -21,6 +21,8 @@
import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.util.Messages;
@@ -61,7 +63,7 @@
public boolean isSystemLibrary() {
return this.isSystemLibrary;
}
-
+
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@@ -97,7 +99,7 @@
/* package */ String serialize() throws IOException {
ByteArrayOutputStream s = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(s, "UTF8"); //$NON-NLS-1$
- XMLWriter xmlWriter = new XMLWriter(writer);
+ XMLWriter xmlWriter = new XMLWriter(writer, null/*use the workspace line delimiter*/);
HashMap library = new HashMap();
library.put(TAG_VERSION, String.valueOf(CURRENT_VERSION));
@@ -105,17 +107,35 @@
xmlWriter.printTag(TAG_USERLIBRARY, library, true, true, false);
for (int i = 0; i < this.entries.length; ++i) {
- IClasspathEntry curr= this.entries[i];
-
+ ClasspathEntry cpEntry = (ClasspathEntry) this.entries[i];
+
HashMap archive = new HashMap();
- archive.put(TAG_PATH, curr.getPath().toString());
- IPath sourceAttach= curr.getSourceAttachmentPath();
+ archive.put(TAG_PATH, cpEntry.getPath().toString());
+ IPath sourceAttach= cpEntry.getSourceAttachmentPath();
if (sourceAttach != null)
archive.put(TAG_SOURCEATTACHMENT, sourceAttach);
- IPath sourceAttachRoot= curr.getSourceAttachmentRootPath();
+ IPath sourceAttachRoot= cpEntry.getSourceAttachmentRootPath();
if (sourceAttachRoot != null)
archive.put(TAG_SOURCEATTACHMENTROOT, sourceAttachRoot);
- xmlWriter.printTag(TAG_ARCHIVE, archive, true, true, true);
+
+ boolean hasExtraAttributes = cpEntry.extraAttributes != null && cpEntry.extraAttributes.length != 0;
+ boolean hasRestrictions = cpEntry.getAccessRuleSet() != null; // access rule set is null if no access rules
+ xmlWriter.printTag(TAG_ARCHIVE, archive, true, true, !(hasExtraAttributes || hasRestrictions));
+
+ // write extra attributes if necessary
+ if (hasExtraAttributes) {
+ cpEntry.encodeExtraAttributes(xmlWriter, true, true);
+ }
+
+ // write extra attributes and restriction if necessary
+ if (hasRestrictions) {
+ cpEntry.encodeAccessRules(xmlWriter, true, true);
+ }
+
+ // write archive end tag if necessary
+ if (hasExtraAttributes || hasRestrictions) {
+ xmlWriter.endTag(TAG_ARCHIVE, true);
+ }
}
xmlWriter.endTag(TAG_USERLIBRARY, true);
writer.flush();
@@ -157,7 +177,10 @@
String path = element.getAttribute(TAG_PATH);
IPath sourceAttach= element.hasAttribute(TAG_SOURCEATTACHMENT) ? new Path(element.getAttribute(TAG_SOURCEATTACHMENT)) : null;
IPath sourceAttachRoot= element.hasAttribute(TAG_SOURCEATTACHMENTROOT) ? new Path(element.getAttribute(TAG_SOURCEATTACHMENTROOT)) : null;
- res.add(JavaCore.newLibraryEntry(new Path(path), sourceAttach, sourceAttachRoot));
+ IClasspathAttribute[] extraAttributes = ClasspathEntry.decodeExtraAttributes(element);
+ IAccessRule[] accessRules = ClasspathEntry.decodeAccessRules(element);
+ IClasspathEntry entry = JavaCore.newLibraryEntry(new Path(path), sourceAttach, sourceAttachRoot, accessRules, extraAttributes, false/*not exported*/);
+ res.add(entry);
}
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java
index 7294367..7fad140 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java
@@ -14,6 +14,9 @@
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
+
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.internal.core.util.Util;
/**
* @since 3.0
*/
@@ -54,10 +57,13 @@
return null;
}
private int tab;
- public XMLWriter(Writer writer) {
+ private String lineSeparator;
+ public XMLWriter(Writer writer, IJavaProject project) {
super(writer);
this.tab= 0;
- println(XML_VERSION);
+ this.lineSeparator = Util.getLineSeparator((String) null, project);
+ print(XML_VERSION);
+ print(this.lineSeparator);
}
public void endTag(String name, boolean insertTab) {
this.tab --;
@@ -89,10 +95,9 @@
if (insertTab) {
printTabulation();
}
+ print(sb.toString());
if (insertNewLine) {
- println(sb.toString());
- } else {
- print(sb.toString());
+ print(this.lineSeparator);
}
if (parameters != null && !closeTag)
this.tab++;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java
index 99202df..b253f44 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java
@@ -59,6 +59,14 @@
IMarker.CHAR_END,
IMarker.LINE_NUMBER,
IJavaModelMarker.ARGUMENTS};
+public final static String[] JAVA_TASK_MARKER_ATTRIBUTE_NAMES = {
+ IMarker.MESSAGE,
+ IMarker.PRIORITY,
+ IJavaModelMarker.ID,
+ IMarker.CHAR_START,
+ IMarker.CHAR_END,
+ IMarker.LINE_NUMBER,
+ IJavaModelMarker.ARGUMENTS};
public final static Integer S_ERROR = new Integer(IMarker.SEVERITY_ERROR);
public final static Integer S_WARNING = new Integer(IMarker.SEVERITY_WARNING);
public final static Integer P_HIGH = new Integer(IMarker.PRIORITY_HIGH);
@@ -313,8 +321,12 @@
option = (String) projectOptions.get(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS);
if (option == null || option.equals(JavaCore.IGNORE)) {
option = (String) projectOptions.get(JavaCore.COMPILER_PB_MISSING_JAVADOC_COMMENTS);
- if (option == null || option.equals(JavaCore.IGNORE))
- projectOptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.DISABLED);
+ if (option == null || option.equals(JavaCore.IGNORE)) {
+ option = (String) projectOptions.get(JavaCore.COMPILER_PB_UNUSED_IMPORT);
+ if (option == null || option.equals(JavaCore.IGNORE)) { // Unused import need also to look inside javadoc comment
+ projectOptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.DISABLED);
+ }
+ }
}
}
@@ -430,11 +442,11 @@
else if (JavaCore.COMPILER_TASK_PRIORITY_LOW.equals(compilerPriority))
priority = P_LOW;
marker.setAttributes(
- JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES,
+ JAVA_TASK_MARKER_ATTRIBUTE_NAMES,
new Object[] {
task.getMessage(),
priority,
- org.eclipse.jdt.internal.compiler.util.Util.toBoolean(false),
+ new Integer(task.getID()),
new Integer(task.getSourceStart()),
new Integer(task.getSourceEnd() + 1),
new Integer(task.getSourceLineNumber()),
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
index b623720..046b1fb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
@@ -219,7 +219,7 @@
createProblemFor(
resource,
null,
- Messages.bind(Messages.build_duplicateResource, (new String[] {id})),
+ Messages.bind(Messages.build_duplicateResource, id),
javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE, true));
return false;
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
index 56ce053..24d54a9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
@@ -17,6 +17,7 @@
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
public class ClasspathDirectory extends ClasspathLocation {
@@ -98,7 +99,8 @@
if (reader != null) {
if (this.accessRuleSet == null)
return new NameEnvironmentAnswer(reader, null);
- return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(qualifiedBinaryFileName.toCharArray()));
+ String fileNameWithoutExtension = qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - SuffixConstants.SUFFIX_CLASS.length);
+ return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(fileNameWithoutExtension.toCharArray()));
}
} catch (Exception e) {
// handle the case when the project is the output folder and the top-level package is a linked folder
@@ -112,7 +114,8 @@
if (reader != null) {
if (this.accessRuleSet == null)
return new NameEnvironmentAnswer(reader, null);
- return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(qualifiedBinaryFileName.toCharArray()));
+ String fileNameWithoutExtension = qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - SuffixConstants.SUFFIX_CLASS.length);
+ return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(fileNameWithoutExtension.toCharArray()));
}
} catch (Exception ignored) { // treat as if class file is missing
}
@@ -149,4 +152,10 @@
return start;
return start + " with " + this.accessRuleSet; //$NON-NLS-1$
}
+
+public String debugPathString() {
+ return this.binaryLocation;
+}
+
+
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
index ba3817b..45bcc8c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
@@ -18,6 +18,7 @@
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.core.util.SimpleSet;
import java.io.*;
@@ -42,21 +43,20 @@
/**
* Calculate and cache the package list available in the zipFile.
- * @param zipFile The zip file to use
+ * @param jar The ClasspathJar to use
* @return A SimpleSet with the all the package names in the zipFile.
*/
-static SimpleSet findPackageSet(ZipFile zipFile) {
- String zipFileName = zipFile.getName();
- File zipFileObject = new File(zipFileName);
- long lastModified = zipFileObject.lastModified();
- long fileSize = zipFileObject.length();
+static SimpleSet findPackageSet(ClasspathJar jar) {
+ String zipFileName = jar.zipFilename;
+ long lastModified = jar.lastModified();
+ long fileSize = new File(zipFileName).length();
PackageCacheEntry cacheEntry = (PackageCacheEntry) PackageCache.get(zipFileName);
if (cacheEntry != null && cacheEntry.lastModified == lastModified && cacheEntry.fileSize == fileSize)
return cacheEntry.packageSet;
SimpleSet packageSet = new SimpleSet(41);
packageSet.add(""); //$NON-NLS-1$
- nextEntry : for (Enumeration e = zipFile.entries(); e.hasMoreElements(); ) {
+ nextEntry : for (Enumeration e = jar.zipFile.entries(); e.hasMoreElements(); ) {
String fileName = ((ZipEntry) e.nextElement()).getName();
// add the package name & all of its parent packages
@@ -79,17 +79,11 @@
String zipFilename; // keep for equals
IFile resource;
ZipFile zipFile;
+long lastModified;
boolean closeZipFileAtEnd;
SimpleSet knownPackageNames;
AccessRuleSet accessRuleSet;
-ClasspathJar(String zipFilename, AccessRuleSet accessRuleSet) {
- this.zipFilename = zipFilename;
- this.zipFile = null;
- this.knownPackageNames = null;
- this.accessRuleSet = accessRuleSet;
-}
-
ClasspathJar(IFile resource, AccessRuleSet accessRuleSet) {
this.resource = resource;
IPath location = resource.getLocation();
@@ -99,6 +93,14 @@
this.accessRuleSet = accessRuleSet;
}
+ClasspathJar(String zipFilename, long lastModified, AccessRuleSet accessRuleSet) {
+ this.zipFilename = zipFilename;
+ this.lastModified = lastModified;
+ this.zipFile = null;
+ this.knownPackageNames = null;
+ this.accessRuleSet = accessRuleSet;
+}
+
public ClasspathJar(ZipFile zipFile, AccessRuleSet accessRuleSet) {
this.zipFilename = zipFile.getName();
this.zipFile = zipFile;
@@ -126,8 +128,8 @@
if (this.accessRuleSet != jar.accessRuleSet)
if (this.accessRuleSet == null || !this.accessRuleSet.equals(jar.accessRuleSet))
return false;
- return this.zipFilename.equals(((ClasspathJar) o).zipFilename);
-}
+ return this.zipFilename.equals(jar.zipFilename) && this.lastModified() == jar.lastModified();
+}
public NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String qualifiedBinaryFileName) {
if (!isPackage(qualifiedPackageName)) return null; // most common case
@@ -137,7 +139,8 @@
if (reader != null) {
if (this.accessRuleSet == null)
return new NameEnvironmentAnswer(reader, null);
- return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(qualifiedBinaryFileName.toCharArray()));
+ String fileNameWithoutExtension = qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - SuffixConstants.SUFFIX_CLASS.length);
+ return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(fileNameWithoutExtension.toCharArray()));
}
} catch (Exception e) { // treat as if class file is missing
}
@@ -161,17 +164,30 @@
this.zipFile = new ZipFile(zipFilename);
this.closeZipFileAtEnd = true;
}
- this.knownPackageNames = findPackageSet(this.zipFile);
+ this.knownPackageNames = findPackageSet(this);
} catch(Exception e) {
this.knownPackageNames = new SimpleSet(); // assume for this build the zipFile is empty
}
return this.knownPackageNames.includes(qualifiedPackageName);
}
+public long lastModified() {
+ if (this.lastModified == 0)
+ this.lastModified = new File(this.zipFilename).lastModified();
+ return this.lastModified;
+}
+
public String toString() {
String start = "Classpath jar file " + this.zipFilename; //$NON-NLS-1$
if (this.accessRuleSet == null)
return start;
return start + " with " + this.accessRuleSet; //$NON-NLS-1$
}
+
+public String debugPathString() {
+ if (this.lastModified == 0)
+ return this.zipFilename;
+ return this.zipFilename + '(' + (new Date(this.lastModified)) + " : " + this.lastModified + ')'; //$NON-NLS-1$
+}
+
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java
index 6db53e7..d7cb036 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java
@@ -26,8 +26,12 @@
return new ClasspathDirectory(binaryFolder, isOutputFolder, accessRuleSet);
}
-static ClasspathLocation forLibrary(String libraryPathname, AccessRuleSet accessRestriction) {
- return new ClasspathJar(libraryPathname, accessRestriction);
+static ClasspathLocation forLibrary(String libraryPathname, long lastModified, AccessRuleSet accessRuleSet) {
+ return new ClasspathJar(libraryPathname, lastModified, accessRuleSet);
+}
+
+static ClasspathLocation forLibrary(String libraryPathname, AccessRuleSet accessRuleSet) {
+ return forLibrary(libraryPathname, 0, accessRuleSet);
}
static ClasspathLocation forLibrary(IFile library, AccessRuleSet accessRuleSet) {
@@ -50,4 +54,7 @@
public void reset() {
// reset any internal caches before another compile loop starts
}
+
+public abstract String debugPathString();
+
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
index 96c32e8..da7935d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
@@ -177,7 +177,7 @@
} catch (MissingClassFileException e) {
// do not log this exception since its thrown to handle aborted compiles because of missing class files
if (DEBUG)
- System.out.println(Messages.bind(Messages.build_incompleteClassPath, (new String[] {e.missingClassFile})));
+ System.out.println(Messages.bind(Messages.build_incompleteClassPath, e.missingClassFile));
IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
marker.setAttribute(IMarker.MESSAGE, Messages.bind(Messages.build_incompleteClassPath, e.missingClassFile));
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
@@ -408,8 +408,10 @@
}
} catch (CoreException ignore) { // skip it
}
- if (DEBUG)
- System.out.println(newSourceLocations[n] + " != " + oldSourceLocations[o]); //$NON-NLS-1$
+ if (DEBUG) {
+ System.out.println("New location: " + newSourceLocations[n] + "\n!= old location: " + oldSourceLocations[o]); //$NON-NLS-1$ //$NON-NLS-2$
+ printLocations(newSourceLocations, oldSourceLocations);
+ }
return true;
}
while (n < newLength) {
@@ -420,13 +422,17 @@
}
} catch (CoreException ignore) { // skip it
}
- if (DEBUG)
+ if (DEBUG) {
System.out.println("Added non-empty source folder"); //$NON-NLS-1$
+ printLocations(newSourceLocations, oldSourceLocations);
+ }
return true;
}
if (o < oldLength) {
- if (DEBUG)
+ if (DEBUG) {
System.out.println("Removed source folder"); //$NON-NLS-1$
+ printLocations(newSourceLocations, oldSourceLocations);
+ }
return true;
}
@@ -436,18 +442,16 @@
oldLength = oldBinaryLocations.length;
for (n = o = 0; n < newLength && o < oldLength; n++, o++) {
if (newBinaryLocations[n].equals(oldBinaryLocations[o])) continue;
- if (DEBUG)
- System.out.println(newBinaryLocations[n] + " != " + oldBinaryLocations[o]); //$NON-NLS-1$
+ if (DEBUG) {
+ System.out.println("New location: " + newBinaryLocations[n] + "\n!= old location: " + oldBinaryLocations[o]); //$NON-NLS-1$ //$NON-NLS-2$
+ printLocations(newBinaryLocations, oldBinaryLocations);
+ }
return true;
}
if (n < newLength || o < oldLength) {
if (DEBUG) {
System.out.println("Number of binary folders/jar files has changed:"); //$NON-NLS-1$
- for (int i = 0; i < newLength; i++)
- System.out.println(newBinaryLocations[i]);
- System.out.println("was:"); //$NON-NLS-1$
- for (int i = 0; i < oldLength; i++)
- System.out.println(oldBinaryLocations[i]);
+ printLocations(newBinaryLocations, oldBinaryLocations);
}
return true;
}
@@ -547,6 +551,9 @@
return false;
}
+ if (JavaCore.WARNING.equals(javaProject.getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true)))
+ return true;
+
// make sure all prereq projects have valid build states... only when aborting builds since projects in cycles do not have build states
// except for projects involved in a 'warning' cycle (see below)
IProject[] requiredProjects = getRequiredProjects(false);
@@ -598,6 +605,15 @@
}
}
+private void printLocations(ClasspathLocation[] newLocations, ClasspathLocation[] oldLocations) {
+ System.out.println("New locations:"); //$NON-NLS-1$
+ for (int i = 0, length = newLocations.length; i < length; i++)
+ System.out.println(" " + newLocations[i].debugPathString()); //$NON-NLS-1$
+ System.out.println("Old locations:"); //$NON-NLS-1$
+ for (int i = 0, length = oldLocations.length; i < length; i++)
+ System.out.println(" " + oldLocations[i].debugPathString()); //$NON-NLS-1$
+}
+
private void recordNewState(State state) {
Object[] keyTable = binaryLocationsPerProject.keyTable;
for (int i = 0, l = keyTable.length; i < l; i++) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
index fccb5fe..f3230c9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
@@ -43,7 +43,7 @@
private StringSet structurallyChangedTypes;
public static int MaxStructurallyChangedTypes = 100; // keep track of ? structurally changed types, otherwise consider all to be changed
-static final byte VERSION = 0x0011; // added discouraged access rules
+public static final byte VERSION = 0x0013; // added timestamps to external jars
static final byte SOURCE_FOLDER = 1;
static final byte BINARY_FOLDER = 2;
@@ -197,10 +197,10 @@
static State read(IProject project, DataInputStream in) throws IOException {
if (JavaBuilder.DEBUG)
- System.out.println("About to read state..."); //$NON-NLS-1$
+ System.out.println("About to read state " + project.getName()); //$NON-NLS-1$
if (VERSION != in.readByte()) {
if (JavaBuilder.DEBUG)
- System.out.println("Found non-compatible state version... answered null"); //$NON-NLS-1$
+ System.out.println("Found non-compatible state version... answered null for " + project.getName()); //$NON-NLS-1$
return null;
}
@@ -244,7 +244,7 @@
newState.binaryLocations[i] = ClasspathLocation.forBinaryFolder(outputFolder, in.readBoolean(), readRestriction(in));
break;
case EXTERNAL_JAR :
- newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF(), readRestriction(in));
+ newState.binaryLocations[i] = ClasspathLocation.forLibrary(in.readUTF(), in.readLong(), readRestriction(in));
break;
case INTERNAL_JAR :
newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())), readRestriction(in));
@@ -426,6 +426,7 @@
if (jar.resource == null) {
out.writeByte(EXTERNAL_JAR);
out.writeUTF(jar.zipFilename);
+ out.writeLong(jar.lastModified());
} else {
out.writeByte(INTERNAL_JAR);
out.writeUTF(jar.resource.getFullPath().toString());
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java
index 1516c51..c960f20 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java
@@ -291,7 +291,8 @@
typeDelta.superTypes();
}
if ((newFlags & IJavaElementDelta.F_MODIFIERS) != 0
- && this.hierarchy.hasSupertype(type.getElementName())) {
+ && (this.hierarchy.hasSupertype(type.getElementName())
+ || type.equals(this.hierarchy.focusType))) {
if (typeDelta == null) {
typeDelta = new SimpleDelta();
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java
index cc6b329..4bb296e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java
@@ -85,8 +85,6 @@
buffer.append('<');
for (int i = 0, length = this.typeParameterSignatures.length; i < length; i++) {
buffer.append(this.typeParameterSignatures[i]);
- if (i != length-1)
- buffer.append(',');
}
buffer.append('>');
if (this.superclass == null)
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java
index 53d8c8b..2fed303 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java
@@ -12,12 +12,10 @@
import java.util.*;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.search.*;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
@@ -35,7 +33,6 @@
import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
import org.eclipse.jdt.internal.core.search.matching.SuperTypeReferencePattern;
import org.eclipse.jdt.internal.core.util.HandleFactory;
-import org.eclipse.jdt.internal.core.util.Util;
public class IndexBasedHierarchyBuilder extends HierarchyBuilder implements SuffixConstants {
public static final int MAXTICKS = 800; // heuristic so that there still progress for deep hierachies
@@ -351,7 +348,9 @@
protected IBinaryType createInfoFromClassFileInJar(Openable classFile) {
String filePath = (((ClassFile)classFile).getType().getFullyQualifiedName('$')).replace('.', '/') + SuffixConstants.SUFFIX_STRING_class;
IPackageFragmentRoot root = classFile.getPackageFragmentRoot();
- String rootPath = root.isExternal() ? root.getPath().toOSString() : root.getPath().toString();
+ IPath path = root.getPath();
+ // take the OS path for external jars, and the forward slash path for internal jars
+ String rootPath = path.getDevice() == null ? path.toString() : path.toOSString();
String documentPath = rootPath + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + filePath;
IBinaryType binaryType = (IBinaryType)this.binariesFromIndexMatches.get(documentPath);
if (binaryType != null) {
@@ -434,14 +433,15 @@
IndexQueryRequestor searchRequestor = new IndexQueryRequestor() {
public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
SuperTypeReferencePattern record = (SuperTypeReferencePattern)indexRecord;
- pathRequestor.acceptPath(documentPath, record.enclosingTypeName == IIndexConstants.ONE_ZERO);
+ boolean isLocalOrAnonymous = record.enclosingTypeName == IIndexConstants.ONE_ZERO;
+ pathRequestor.acceptPath(documentPath, isLocalOrAnonymous);
char[] typeName = record.simpleName;
int suffix = documentPath.toLowerCase().indexOf(SUFFIX_STRING_class);
if (suffix != -1){
HierarchyBinaryType binaryType = (HierarchyBinaryType)binariesFromIndexMatches.get(documentPath);
if (binaryType == null){
char[] enclosingTypeName = record.enclosingTypeName;
- if (enclosingTypeName == IIndexConstants.ONE_ZERO) { // local or anonymous type
+ if (isLocalOrAnonymous) {
int lastSlash = documentPath.lastIndexOf('/');
int lastDollar = documentPath.lastIndexOf('$');
if (lastDollar == -1) {
@@ -451,7 +451,7 @@
typeName = documentPath.substring(lastSlash+1, suffix).toCharArray();
} else {
enclosingTypeName = documentPath.substring(lastSlash+1, lastDollar).toCharArray();
- typeName = Util.localTypeName(documentPath, lastDollar, suffix).toCharArray();
+ typeName = documentPath.substring(lastDollar+1, suffix).toCharArray();
}
}
binaryType = new HierarchyBinaryType(record.modifiers, record.pkgName, typeName, enclosingTypeName, record.typeParameterSignatures, record.classOrInterface);
@@ -459,7 +459,8 @@
}
binaryType.recordSuperType(record.superSimpleName, record.superQualification, record.superClassOrInterface);
}
- if (!foundSuperNames.containsKey(typeName)){
+ if (!isLocalOrAnonymous // local or anonymous types cannot have subtypes outside the cu that define them
+ && !foundSuperNames.containsKey(typeName)){
foundSuperNames.put(typeName, typeName);
queue.add(typeName);
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java
index 2a5f271..8c8609b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java
@@ -880,6 +880,17 @@
return true;
}
}
+ if (this.focusType != null) {
+ // if the hierarchy's project is on the added project classpath, then the hierarchy has changed
+ classpath = ((JavaProject)element).getExpandedClasspath(true);
+ IPath hierarchyProject = javaProject().getPath();
+ for (int i = 0; i < classpath.length; i++) {
+ if (classpath[i].getEntryKind() == IClasspathEntry.CPE_PROJECT
+ && classpath[i].getPath().equals(hierarchyProject)) {
+ return true;
+ }
+ }
+ }
return false;
} catch (JavaModelException e) {
return false;
@@ -1470,7 +1481,7 @@
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("Focus: "); //$NON-NLS-1$
- buffer.append(this.focusType == null ? "<NONE>" : ((JavaElement)this.focusType).toStringWithAncestors()); //$NON-NLS-1$
+ buffer.append(this.focusType == null ? "<NONE>" : ((JavaElement)this.focusType).toStringWithAncestors(false/*don't show key*/)); //$NON-NLS-1$
buffer.append("\n"); //$NON-NLS-1$
if (exists()) {
if (this.focusType != null) {
@@ -1513,7 +1524,7 @@
buffer.append(" "); //$NON-NLS-1$
}
JavaElement element = (JavaElement)types[i];
- buffer.append(element.toStringWithAncestors());
+ buffer.append(element.toStringWithAncestors(false/*don't show key*/));
buffer.append('\n');
toString(buffer, types[i], indent + 1, ascendant);
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java
index 257993c..eba8825 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java
@@ -18,6 +18,7 @@
import org.eclipse.jdt.core.jdom.*;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Util;
/**
* DOMField provides an implementation of IDOMField.
*
@@ -381,16 +382,16 @@
.append('=')
.append(fInitializer)
.append(';')
- .append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR);
+ .append(Util.getLineSeparator(buffer.toString(), null));
} else {
buffer
.append(fDocument, fNameRange[1] + 1, fInitializerRange[0] - fNameRange[1] - 1)
.append(getInitializer())
.append(';')
- .append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR);
+ .append(Util.getLineSeparator(buffer.toString(), null));
}
} else {
- buffer.append(';').append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR);
+ buffer.append(';').append(Util.getLineSeparator(buffer.toString(), null));
}
return buffer.getContents();
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java
index 595da2e..1a99239 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java
@@ -16,6 +16,7 @@
import org.eclipse.jdt.core.jdom.*;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Util;
/**
* DOMImport provides an implementation of IDOMImport.
@@ -99,7 +100,7 @@
.append("import ") //$NON-NLS-1$
.append(fName)
.append(';')
- .append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR);
+ .append(Util.getLineSeparator(buffer.toString(), null));
} else {
buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]);
//buffer.append(fDocument, fNameRange[0], fNameRange[1] - fNameRange[0] + 1);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java
index 1bd97cf..cba8276 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java
@@ -15,6 +15,7 @@
import org.eclipse.jdt.core.jdom.*;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Util;
/**
* DOMInitializer provides an implementation of IDOMInitializer.
*
@@ -107,7 +108,7 @@
.append(getBody())
.append(fDocument, fBodyRange[1] + 1, fSourceRange[1] - fBodyRange[1]);
} else {
- buffer.append("{}").append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR); //$NON-NLS-1$
+ buffer.append("{}").append(Util.getLineSeparator(buffer.toString(), null)); //$NON-NLS-1$
}
}
/**
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java
index 92f15c4..c83d0eb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java
@@ -18,6 +18,7 @@
import org.eclipse.jdt.core.jdom.*;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Util;
/**
* DOMMethod provides an implementation of IDOMMethod.
*
@@ -599,7 +600,7 @@
fBody= body;
setHasBody(body != null);
if (!hasBody()) {
- fBody= ";" + org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR; //$NON-NLS-1$
+ fBody= ";" + Util.getLineSeparator(body, null); //$NON-NLS-1$
}
}
/**
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java
index a6ab806..3bc7454 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java
@@ -15,6 +15,7 @@
import org.eclipse.jdt.core.jdom.*;
import org.eclipse.jdt.internal.core.util.Messages;
import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Util;
/**
* DOMPackage provides an implementation of IDOMPackage.
@@ -76,12 +77,13 @@
*/
protected void appendFragmentedContents(CharArrayBuffer buffer) {
if (fNameRange[0] < 0) {
+ String lineSeparator = Util.getLineSeparator(buffer.toString(), null);
buffer
.append("package ") //$NON-NLS-1$
.append(fName)
.append(';')
- .append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR)
- .append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR);
+ .append(lineSeparator)
+ .append(lineSeparator);
} else {
buffer
.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0])
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java
index 9140e31..81b4fe7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java
@@ -27,7 +27,8 @@
static final int FLAGS = 6;
static final int WILDCARD = 7;
static final int CAPTURE = 8;
- static final int END = 9;
+ static final int BASE_TYPE = 9;
+ static final int END = 10;
static final int START = -1;
@@ -46,6 +47,12 @@
return result;
}
+ boolean isAtCaptureStart() {
+ return
+ this.index < this.source.length
+ && this.source[this.index] == '!';
+ }
+
boolean isAtFieldOrMethodStart() {
return
this.index < this.source.length
@@ -93,6 +100,12 @@
&& this.source[this.index] == '~';
}
+ boolean isAtWildcardStart() {
+ return
+ this.index < this.source.length
+ && "*+-".indexOf(this.source[this.index]) != -1; //$NON-NLS-1$
+ }
+
boolean isAtTypeParameterStart() {
return
this.index < this.source.length
@@ -100,27 +113,27 @@
}
boolean isAtTypeArgumentStart() {
- return this.index < this.source.length && "LIZVCDBFJS[*+-!".indexOf(this.source[this.index]) != -1; //$NON-NLS-1$
+ return this.index < this.source.length && "LIZVCDBFJS[!".indexOf(this.source[this.index]) != -1; //$NON-NLS-1$
}
- boolean isAtMethodTypeVariableStart() {
- return
- this.index < this.source.length
- && this.source[this.index] == ':';
- }
-
boolean isAtFlagsStart() {
return
this.index < this.source.length
&& this.source[this.index] == '^';
}
- boolean isAtTypeTypeVariableStart() {
+ boolean isAtTypeVariableStart() {
return
this.index < this.source.length
&& this.source[this.index] == ':';
}
+ boolean isAtTypeWithCaptureStart() {
+ return
+ this.index < this.source.length
+ && this.source[this.index] == '&';
+ }
+
int nextToken() {
int previousTokenEnd = this.index;
this.start = this.index;
@@ -139,9 +152,10 @@
case 'V':
case 'Z':
// base type
- if (this.index == previousTokenEnd) {
+ if (this.index == previousTokenEnd
+ && (this.index == 0 || this.source[this.index-1] != '.')) { // case of field or method starting with one of the character above
this.index++;
- this.token = TYPE;
+ this.token = BASE_TYPE;
return this.token;
}
break;
@@ -175,6 +189,7 @@
this.token = LOCAL_VAR;
break;
case TYPE:
+ case BASE_TYPE:
if (this.index > this.start && this.source[this.start-1] == '.')
this.token = FIELD;
break;
@@ -203,10 +218,7 @@
this.token = ARRAY;
return this.token;
case '<':
- if (this.index == previousTokenEnd) {
- this.start = this.index+1;
- previousTokenEnd = this.start;
- } else if (this.start > 0) {
+ if (this.start > 0) {
switch (this.source[this.start-1]) {
case '.':
if (this.source[this.start-2] == '>')
@@ -216,8 +228,13 @@
this.token = METHOD;
return this.token;
default:
- this.token = TYPE;
- return this.token;
+ if (this.index == previousTokenEnd) {
+ this.start = this.index+1;
+ previousTokenEnd = this.start;
+ } else {
+ this.token = TYPE;
+ return this.token;
+ }
}
}
break;
@@ -225,9 +242,13 @@
this.token = METHOD;
return this.token;
case ')':
- this.start = ++this.index;
- this.token = END;
- return this.token;
+ if (this.token == TYPE) {
+ this.token = FIELD;
+ return this.token;
+ }
+ this.start = this.index+1;
+ previousTokenEnd = this.start;
+ break;
case '#':
if (this.index == previousTokenEnd) {
this.start = this.index+1;
@@ -252,6 +273,9 @@
else
this.token = END;
break;
+ case WILDCARD:
+ this.token = TYPE;
+ break;
default:
this.token = END;
break;
@@ -264,6 +288,7 @@
this.token = WILDCARD;
return this.token;
case '!':
+ case '&':
this.index++;
this.token = CAPTURE;
return this.token;
@@ -301,7 +326,7 @@
}
void skipParametersStart() {
- if (this.index < this.source.length && this.source[this.index] == '<')
+ while (this.index < this.source.length && (this.source[this.index] == '<' || this.source[this.index] == '%'))
this.index++;
}
@@ -343,6 +368,15 @@
case FLAGS:
buffer.append("MODIFIERS: "); //$NON-NLS-1$
break;
+ case WILDCARD:
+ buffer.append("WILDCARD: "); //$NON-NLS-1$
+ break;
+ case CAPTURE:
+ buffer.append("CAPTURE: "); //$NON-NLS-1$
+ break;
+ case BASE_TYPE:
+ buffer.append("BASE TYPE: "); //$NON-NLS-1$
+ break;
case END:
buffer.append("END: "); //$NON-NLS-1$
break;
@@ -387,7 +421,11 @@
// default is to do nothing
}
- public void consumeCapture() {
+ public void consumeBaseType(char[] baseTypeSig) {
+ // default is to do nothing
+ }
+
+ public void consumeCapture(int position) {
// default is to do nothing
}
@@ -395,7 +433,7 @@
// default is to do nothing
}
- public void consumeParameterizedMethod() {
+ public void consumeParameterizedGenericMethod() {
// default is to do nothing
}
@@ -451,6 +489,10 @@
// default is to do nothing
}
+ public void consumeKey() {
+ // default is to do nothing
+ }
+
public void consumeTopLevelType() {
// default is to do nothing
}
@@ -463,10 +505,14 @@
// default is to do nothing
}
- public void consumeTypeVariable(char[] typeVariableName) {
+ public void consumeTypeVariable(char[] position, char[] typeVariableName) {
// default is to do nothing
}
+ public void consumeTypeWithCapture() {
+ // default is to do nothing
+ }
+
public void consumeWildCard(int kind) {
// default is to do nothing
}
@@ -503,8 +549,10 @@
return;
}
}
- if (!hasTypeName())
+ if (!hasTypeName()) {
+ consumeKey();
return;
+ }
consumeTopLevelType();
parseSecondaryType();
parseInnerType();
@@ -520,7 +568,7 @@
parseInnerType();
} else if (this.scanner.isAtTypeArgumentStart())
// parameterized type
- parseParameterizedType(null/*top level type*/, false/*no raw*/);
+ parseParameterizedType(null/*top level type or member type with raw enclosing type*/, false/*no raw*/);
else if (this.scanner.isAtRawTypeEnd())
// raw type
parseRawType();
@@ -536,14 +584,13 @@
if (this.scanner.isAtFieldOrMethodStart()) {
switch (this.scanner.nextToken()) {
case Scanner.FIELD:
- consumeField(this.scanner.getTokenSource());
- parseFlags();
+ parseField();
return;
case Scanner.METHOD:
parseMethod();
if (this.scanner.isAtLocalVariableStart()) {
parseLocalVariable();
- } else if (this.scanner.isAtMethodTypeVariableStart()) {
+ } else if (this.scanner.isAtTypeVariableStart()) {
parseTypeVariable();
}
break;
@@ -551,12 +598,23 @@
malformedKey();
return;
}
- } else if (this.scanner.isAtTypeTypeVariableStart()) {
+ } else if (this.scanner.isAtTypeVariableStart()) {
parseTypeVariable();
+ } else if (this.scanner.isAtWildcardStart()) {
+ parseWildcard();
+ } else if (this.scanner.isAtTypeWithCaptureStart()) {
+ parseTypeWithCapture();
}
+
+ consumeKey();
}
private void parseFullyQualifiedName() {
+ if (this.scanner.isAtCaptureStart()) {
+ parseCapture();
+ this.hasTypeName = false;
+ return;
+ }
switch(this.scanner.nextToken()) {
case Scanner.PACKAGE:
this.keyStart = 0;
@@ -567,49 +625,27 @@
this.keyStart = this.scanner.start-1;
consumeFullyQualifiedName(this.scanner.getTokenSource());
break;
+ case Scanner.BASE_TYPE:
+ this.keyStart = this.scanner.start-1;
+ consumeBaseType(this.scanner.getTokenSource());
+ this.hasTypeName = false;
+ break;
case Scanner.ARRAY:
this.keyStart = this.scanner.start;
consumeArrayDimension(this.scanner.getTokenSource());
- if (this.scanner.nextToken() == Scanner.TYPE)
- consumeFullyQualifiedName(this.scanner.getTokenSource());
- else {
- malformedKey();
- return;
+ switch (this.scanner.nextToken()) {
+ case Scanner.TYPE:
+ consumeFullyQualifiedName(this.scanner.getTokenSource());
+ break;
+ case Scanner.BASE_TYPE:
+ consumeBaseType(this.scanner.getTokenSource());
+ this.hasTypeName = false;
+ break;
+ default:
+ malformedKey();
+ return;
}
break;
- case Scanner.WILDCARD:
- char[] source = this.scanner.getTokenSource();
- if (source.length == 0) {
- malformedKey();
- return;
- }
- int kind = -1;
- switch (source[0]) {
- case '*':
- kind = Wildcard.UNBOUND;
- break;
- case '+':
- kind = Wildcard.EXTENDS;
- break;
- case '-':
- kind = Wildcard.SUPER;
- break;
- }
- if (kind == -1) {
- malformedKey();
- return;
- }
- consumeWildCard(kind);
- if (kind == Wildcard.UNBOUND) {
- this.hasTypeName = false;
- return;
- }
- parseFullyQualifiedName();
- break;
- case Scanner.CAPTURE:
- consumeCapture();
- parseFullyQualifiedName();
- break;
default:
malformedKey();
return;
@@ -617,10 +653,11 @@
}
private void parseParameterizedMethod() {
+ this.scanner.skipParametersStart();
while (!this.scanner.isAtParametersEnd()) {
parseTypeArgument();
}
- consumeParameterizedMethod();
+ consumeParameterizedGenericMethod();
}
private void parseGenericType() {
@@ -681,6 +718,31 @@
parseParameterizedMethod();
}
+ private void parseCapture() {
+ if (this.scanner.nextToken() != Scanner.CAPTURE) return;
+ parseCaptureWildcard();
+ if (this.scanner.nextToken() != Scanner.TYPE) {
+ malformedKey();
+ return;
+ }
+ char[] positionChars = this.scanner.getTokenSource();
+ int position = Integer.parseInt(new String(positionChars));
+ consumeCapture(position);
+ this.scanner.skipTypeEnd();
+ }
+
+ private void parseCaptureWildcard() {
+ BindingKeyParser parser = newParser();
+ parser.parse();
+ consumeParser(parser);
+ }
+
+ private void parseField() {
+ char[] fieldName = this.scanner.getTokenSource();
+ parseReturnType();
+ consumeField(fieldName);
+ }
+
private void parseFlags() {
if (!this.scanner.isAtFlagsStart() || this.scanner.nextToken() != Scanner.FLAGS) return;
consumeModifiers(this.scanner.getTokenSource());
@@ -712,6 +774,12 @@
consumeRawType();
}
+ private void parseReturnType() {
+ BindingKeyParser parser = newParser();
+ parser.parse();
+ consumeParser(parser);
+ }
+
private void parseSecondaryType() {
if (!this.scanner.isAtSecondaryTypeStart() || this.scanner.nextToken() != Scanner.TYPE) return;
consumeSecondaryType(this.scanner.getTokenSource());
@@ -723,13 +791,65 @@
consumeParser(parser);
}
+ private void parseTypeWithCapture() {
+ if (this.scanner.nextToken() != Scanner.CAPTURE) return;
+ BindingKeyParser parser = newParser();
+ parser.parse();
+ consumeParser(parser);
+ consumeTypeWithCapture();
+ }
+
private void parseTypeVariable() {
if (this.scanner.nextToken() != Scanner.TYPE) {
malformedKey();
return;
}
- consumeTypeVariable(this.scanner.getTokenSource());
+ char[] typeVariableName = this.scanner.getTokenSource();
+ char[] position;
+ int length = typeVariableName.length;
+ if (length > 0 && Character.isDigit(typeVariableName[0])) {
+ int firstT = CharOperation.indexOf('T', typeVariableName);
+ position = CharOperation.subarray(typeVariableName, 0, firstT);
+ typeVariableName = CharOperation.subarray(typeVariableName, firstT+1, typeVariableName.length);
+ } else {
+ position = CharOperation.NO_CHAR;
+ }
+ consumeTypeVariable(position, typeVariableName);
this.scanner.skipTypeEnd();
}
+ private void parseWildcard() {
+ if (this.scanner.nextToken() != Scanner.WILDCARD) return;
+ char[] source = this.scanner.getTokenSource();
+ if (source.length == 0) {
+ malformedKey();
+ return;
+ }
+ int kind = -1;
+ switch (source[0]) {
+ case '*':
+ kind = Wildcard.UNBOUND;
+ break;
+ case '+':
+ kind = Wildcard.EXTENDS;
+ break;
+ case '-':
+ kind = Wildcard.SUPER;
+ break;
+ }
+ if (kind == -1) {
+ malformedKey();
+ return;
+ }
+ if (kind != Wildcard.UNBOUND)
+ parseWildcardBound();
+ consumeWildCard(kind);
+ }
+
+ private void parseWildcardBound() {
+ BindingKeyParser parser = newParser();
+ parser.parse();
+ consumeParser(parser);
+ }
+
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
index d5f21f9..27c74f2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
@@ -13,10 +13,20 @@
import java.util.ArrayList;
import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
+import org.eclipse.jdt.internal.compiler.ast.Assignment;
+import org.eclipse.jdt.internal.compiler.ast.CastExpression;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
+import org.eclipse.jdt.internal.compiler.ast.FieldReference;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypes;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
@@ -29,6 +39,8 @@
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
@@ -50,14 +62,18 @@
TypeBinding typeBinding;
TypeDeclaration typeDeclaration;
ArrayList types = new ArrayList();
+ int rank = 0;
- boolean isCapture;
- int wildcardKind = -1;
+ int wildcardRank;
- private BindingKeyResolver(BindingKeyParser parser, Compiler compiler, LookupEnvironment environment) {
+ CompilationUnitDeclaration outerMostParsedUnit;
+
+ private BindingKeyResolver(BindingKeyParser parser, Compiler compiler, LookupEnvironment environment, int wildcardRank, CompilationUnitDeclaration outerMostParsedUnit) {
super(parser);
this.compiler = compiler;
this.environment = environment;
+ this.wildcardRank = wildcardRank;
+ this.outerMostParsedUnit = outerMostParsedUnit;
}
public BindingKeyResolver(String key) {
@@ -84,8 +100,92 @@
this.dimension = brakets.length;
}
- public void consumeCapture() {
- this.isCapture = true;
+ public void consumeBaseType(char[] baseTypeSig) {
+ this.compoundName = new char[][] {getKey().toCharArray()};
+ TypeBinding baseTypeBinding = getBaseTypeBinding(baseTypeSig);
+ if (baseTypeBinding != null) {
+ this.typeBinding = baseTypeBinding;
+ }
+ }
+
+ public void consumeCapture(final int position) {
+ CompilationUnitDeclaration outerParsedUnit = this.outerMostParsedUnit == null ? this.parsedUnit : this.outerMostParsedUnit;
+ if (outerParsedUnit == null) return;
+ final Binding wildcardBinding = ((BindingKeyResolver) this.types.get(0)).compilerBinding;
+ class CaptureFinder extends ASTVisitor {
+ CaptureBinding capture;
+ boolean checkType(TypeBinding binding) {
+ if (binding == null)
+ return false;
+ switch (binding.kind()) {
+ case Binding.PARAMETERIZED_TYPE:
+ TypeBinding[] arguments = ((ParameterizedTypeBinding) binding).arguments;
+ if (arguments == null) return false;
+ for (int i = 0, length = arguments.length; i < length; i++) {
+ if (checkType(arguments[i]))
+ return true;
+ }
+ break;
+ case Binding.WILDCARD_TYPE:
+ return checkType(((WildcardBinding) binding).bound);
+ case Binding.ARRAY_TYPE:
+ return checkType(((ArrayBinding) binding).leafComponentType);
+ case Binding.TYPE_PARAMETER:
+ if (binding.isCapture()) {
+ CaptureBinding captureBinding = (CaptureBinding) binding;
+ if (captureBinding.position == position && captureBinding.wildcard == wildcardBinding) {
+ this.capture = captureBinding;
+ return true;
+ }
+ }
+ break;
+ }
+ return false;
+ }
+ public boolean visit(SingleNameReference singleNameReference, BlockScope blockScope) {
+ if (checkType(singleNameReference.resolvedType))
+ return false;
+ return super.visit(singleNameReference, blockScope);
+ }
+ public boolean visit(QualifiedNameReference qualifiedNameReference, BlockScope blockScope) {
+ if (checkType(qualifiedNameReference.resolvedType))
+ return false;
+ return super.visit(qualifiedNameReference, blockScope);
+ }
+ public boolean visit(MessageSend messageSend, BlockScope blockScope) {
+ if (checkType(messageSend.resolvedType))
+ return false;
+ return super.visit(messageSend, blockScope);
+ }
+ public boolean visit(FieldReference fieldReference, BlockScope blockScope) {
+ if (checkType(fieldReference.resolvedType))
+ return false;
+ return super.visit(fieldReference, blockScope);
+ }
+ public boolean visit(ConditionalExpression conditionalExpression, BlockScope blockScope) {
+ if (checkType(conditionalExpression.resolvedType))
+ return false;
+ return super.visit(conditionalExpression, blockScope);
+ }
+ public boolean visit(CastExpression castExpression, BlockScope blockScope) {
+ if (checkType(castExpression.resolvedType))
+ return false;
+ return super.visit(castExpression, blockScope);
+ }
+ public boolean visit(Assignment assignment, BlockScope blockScope) {
+ if (checkType(assignment.resolvedType))
+ return false;
+ return super.visit(assignment, blockScope);
+ }
+ public boolean visit(ArrayReference arrayReference, BlockScope blockScope) {
+ if (checkType(arrayReference.resolvedType))
+ return false;
+ return super.visit(arrayReference, blockScope);
+ }
+ }
+ CaptureFinder captureFinder = new CaptureFinder();
+ outerParsedUnit.traverse(captureFinder, outerParsedUnit.scope);
+ this.typeBinding = captureFinder.capture;
}
public void consumeField(char[] fieldName) {
@@ -93,25 +193,29 @@
for (int i = 0, length = fields.length; i < length; i++) {
FieldBinding field = fields[i];
if (CharOperation.equals(fieldName, field.name)) {
+ this.typeBinding = null;
this.compilerBinding = field;
return;
}
}
}
- public void consumeParameterizedMethod() {
+ public void consumeParameterizedGenericMethod() {
+ if (this.methodBinding == null)
+ return;
TypeBinding[] arguments = getTypeBindingArguments();
- if (arguments.length != this.methodBinding.typeVariables().length) return;
- this.methodBinding = new ParameterizedGenericMethodBinding(this.methodBinding, arguments, this.environment);
+ if (arguments.length != this.methodBinding.typeVariables().length)
+ this.methodBinding = new ParameterizedGenericMethodBinding(this.methodBinding, (RawTypeBinding) null, this.environment);
+ else
+ this.methodBinding = new ParameterizedGenericMethodBinding(this.methodBinding, arguments, this.environment);
this.compilerBinding = this.methodBinding;
}
public void consumeLocalType(char[] uniqueKey) {
LocalTypeBinding[] localTypeBindings = this.parsedUnit.localTypes;
for (int i = 0; i < this.parsedUnit.localTypeCount; i++)
- if (CharOperation.equals(uniqueKey, localTypeBindings[i].computeUniqueKey(false/*without access flags*/))) {
+ if (CharOperation.equals(uniqueKey, localTypeBindings[i].computeUniqueKey(false/*not a leaf*/))) {
this.typeBinding = localTypeBindings[i];
- this.compilerBinding = this.typeBinding;
return;
}
}
@@ -123,6 +227,7 @@
for (int i = 0; i < this.scope.localIndex; i++) {
LocalVariableBinding local = this.scope.locals[i];
if (CharOperation.equals(varName, local.name)) {
+ this.methodBinding = null;
this.compilerBinding = local;
return;
}
@@ -134,10 +239,11 @@
for (int i = 0, methodLength = methods.length; i < methodLength; i++) {
MethodBinding method = methods[i];
if (CharOperation.equals(selector, method.selector) || (selector.length == 0 && method.isConstructor())) {
- char[] methodSignature = method.original().genericSignature();
+ char[] methodSignature = method.genericSignature();
if (methodSignature == null)
methodSignature = method.signature();
if (CharOperation.equals(signature, methodSignature)) {
+ this.typeBinding = null;
this.methodBinding = method;
this.compilerBinding = this.methodBinding;
return;
@@ -148,7 +254,6 @@
public void consumeMemberType(char[] simpleTypeName) {
this.typeBinding = getTypeBinding(simpleTypeName);
- this.compilerBinding = this.typeBinding;
}
public void consumePackage(char[] pkgName) {
@@ -159,7 +264,7 @@
public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
TypeBinding[] arguments = getTypeBindingArguments();
if (simpleTypeName != null) {
- // parameterized member type
+ // parameterized member type with parameterized enclosing type
this.genericType = this.genericType.getMemberType(simpleTypeName);
if (!isRaw)
this.typeBinding = this.environment.createParameterizedType(this.genericType, arguments, (ReferenceBinding) this.typeBinding);
@@ -167,16 +272,19 @@
// raw type
this.typeBinding = this.environment.createRawType(this.genericType, (ReferenceBinding) this.typeBinding);
} else {
- // parameterized top level type
+ // parameterized top level type or parameterized member type with raw enclosing type
this.genericType = (ReferenceBinding) this.typeBinding;
- this.typeBinding = this.environment.createParameterizedType(this.genericType, arguments, null);
+ ReferenceBinding enclosing = this.genericType.enclosingType();
+ if (enclosing != null) enclosing = (ReferenceBinding) this.environment.convertToRawType(enclosing);
+ this.typeBinding = this.environment.createParameterizedType(this.genericType, arguments, enclosing);
}
- this.compilerBinding = this.typeBinding;
}
public void consumeParser(BindingKeyParser parser) {
this.types.add(parser);
+ if (((BindingKeyResolver) parser).compilerBinding instanceof WildcardBinding)
+ this.rank++;
}
public void consumeScope(int scopeNumber) {
@@ -190,13 +298,12 @@
public void consumeRawType() {
if (this.typeBinding == null) return;
- this.typeBinding = this.environment.createRawType((ReferenceBinding) this.typeBinding, null/*no enclosing type*/);
+ this.typeBinding = this.environment.createRawType((ReferenceBinding) this.typeBinding, this.typeBinding.enclosingType());
}
public void consumeSecondaryType(char[] simpleTypeName) {
if (this.parsedUnit == null) return;
this.typeDeclaration = null; // start from the parsed unit
this.typeBinding = getTypeBinding(simpleTypeName);
- this.compilerBinding = this.typeBinding;
}
public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
@@ -204,47 +311,59 @@
}
public void consumeTopLevelType() {
- if (this.compoundName.length == 1 && this.compoundName[0].length == 1) {
- // case of base type
- TypeBinding baseTypeBinding = getBaseTypeBinding(this.compoundName[0]);
- if (baseTypeBinding != null) {
- this.typeBinding = baseTypeBinding;
- this.compilerBinding = this.typeBinding;
- return;
- }
- }
this.parsedUnit = getCompilationUnitDeclaration();
if (this.parsedUnit != null && this.compiler != null) {
this.compiler.process(this.parsedUnit, this.compiler.totalUnits+1); // noop if unit has already been resolved
}
if (this.parsedUnit == null) {
this.typeBinding = getBinaryBinding();
- this.compilerBinding = this.typeBinding;
} else {
char[] typeName = this.compoundName[this.compoundName.length-1];
this.typeBinding = getTypeBinding(typeName);
+ }
+ }
+
+ public void consumeKey() {
+ if (this.typeBinding != null) {
+ this.typeBinding = getArrayBinding(this.dimension, this.typeBinding);
this.compilerBinding = this.typeBinding;
}
}
- public void consumeType() {
- this.typeBinding = getArrayBinding(this.dimension, this.typeBinding);
- this.compilerBinding = this.typeBinding;
- }
-
- public void consumeTypeVariable(char[] typeVariableName) {
+ public void consumeTypeVariable(char[] position, char[] typeVariableName) {
+ if (position.length > 0) {
+ int pos = Integer.parseInt(new String(position));
+ MethodBinding[] methods = ((ReferenceBinding) this.typeBinding).methods();
+ if (methods != null && pos < methods.length) {
+ this.methodBinding = methods[pos];
+ }
+ }
TypeVariableBinding[] typeVariableBindings = this.methodBinding != null ? this.methodBinding.typeVariables() : this.typeBinding.typeVariables();
for (int i = 0, length = typeVariableBindings.length; i < length; i++) {
TypeVariableBinding typeVariableBinding = typeVariableBindings[i];
if (CharOperation.equals(typeVariableName, typeVariableBinding.sourceName())) {
- this.compilerBinding = typeVariableBinding;
+ this.typeBinding = typeVariableBinding;
return;
}
}
}
+ public void consumeTypeWithCapture() {
+ BindingKeyResolver resolver = (BindingKeyResolver) this.types.get(0);
+ this.typeBinding =(TypeBinding) resolver.compilerBinding;
+ }
+
public void consumeWildCard(int kind) {
- this.wildcardKind = kind;
+ switch (kind) {
+ case Wildcard.EXTENDS:
+ case Wildcard.SUPER:
+ BindingKeyResolver boundResolver = (BindingKeyResolver) this.types.get(0);
+ this.typeBinding = this.environment.createWildcard((ReferenceBinding) this.typeBinding, this.wildcardRank, (TypeBinding) boundResolver.compilerBinding, null /*no extra bound*/, kind);
+ break;
+ case Wildcard.UNBOUND:
+ this.typeBinding = this.environment.createWildcard((ReferenceBinding) this.typeBinding, rank++, null/*no bound*/, null /*no extra bound*/, kind);
+ break;
+ }
}
/*
@@ -290,6 +409,7 @@
* Returns null if not found.
*/
private TypeBinding getBinaryBinding() {
+ if (this.compoundName.length == 0) return null;
return this.environment.getType(this.compoundName);
}
@@ -343,25 +463,9 @@
private TypeBinding[] getTypeBindingArguments() {
int size = this.types.size();
TypeBinding[] arguments = new TypeBinding[size];
- int rank = 0;
for (int i = 0; i < size; i++) {
BindingKeyResolver resolver = (BindingKeyResolver) this.types.get(i);
- TypeBinding binding;
- int kind = resolver.wildcardKind;
- switch (kind) {
- case Wildcard.EXTENDS:
- case Wildcard.SUPER:
- binding = this.environment.createWildcard((ReferenceBinding) this.typeBinding, rank++, (TypeBinding) resolver.compilerBinding, null /*no extra bound*/, kind);
- break;
- case Wildcard.UNBOUND:
- binding = this.environment.createWildcard((ReferenceBinding) this.typeBinding, rank++, null/*no bound*/, null /*no extra bound*/, kind);
- break;
- default:
- binding = (TypeBinding) resolver.compilerBinding;
- }
- if (resolver.isCapture)
- binding = new CaptureBinding((WildcardBinding) binding);
- arguments[i] = binding;
+ arguments[i] = (TypeBinding) resolver.compilerBinding;
}
this.types = new ArrayList();
return arguments;
@@ -372,7 +476,7 @@
}
public BindingKeyParser newParser() {
- return new BindingKeyResolver(this, this.compiler, this.environment);
+ return new BindingKeyResolver(this, this.compiler, this.environment, this.rank, this.outerMostParsedUnit == null ? this.parsedUnit : this.outerMostParsedUnit);
}
public String toString() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java
index 94046cc..541adfc 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java
@@ -11,7 +11,6 @@
package org.eclipse.jdt.internal.core.util;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
@@ -50,8 +49,6 @@
boolean checkDeprecated = false;
int lastCommentIndex = -1;
- //
-
//since jdk1.2 look only in the last java doc comment...
nextComment : for (lastCommentIndex = this.scanner.commentPtr; lastCommentIndex >= 0; lastCommentIndex--){
//look for @deprecated into the first javadoc comment preceeding the declaration
@@ -113,24 +110,6 @@
super.consumeInterfaceHeader();
}
- protected void consumeInternalCompilationUnit() {
- // InternalCompilationUnit ::= PackageDeclaration
- // InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
- // InternalCompilationUnit ::= ImportDeclarations ReduceImports
- }
- protected void consumeInternalCompilationUnitWithTypes() {
- // InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
- // InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
- // InternalCompilationUnit ::= TypeDeclarations
- // InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
- // consume type declarations
- int length;
- if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
- this.compilationUnit.types = new TypeDeclaration[length];
- this.astPtr -= length;
- System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
- }
- }
/**
* Insure that start position is always positive.
* @see org.eclipse.jdt.internal.compiler.parser.Parser#containsComment(int, int)
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java
index 6632b61..e672880 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core.util;
+import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
import org.eclipse.jdt.core.util.IBytecodeVisitor;
@@ -26,6 +27,7 @@
*/
public class DefaultBytecodeVisitor implements IBytecodeVisitor {
private static final String EMPTY_CLASS_NAME = "\"\""; //$NON-NLS-1$
+ private static final String EMPTY_LOCAL_NAME = ""; //$NON-NLS-1$
private static final int T_BOOLEAN = 4;
private static final int T_CHAR = 5;
private static final int T_FLOAT = 6;
@@ -115,10 +117,10 @@
*/
public void _aload_1(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_1],
getLocalVariableName(pc, 1)
- })));
+ }));
writeNewLine();
}
@@ -127,10 +129,10 @@
*/
public void _aload_2(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_2],
getLocalVariableName(pc, 2)
- })));
+ }));
writeNewLine();
}
@@ -139,10 +141,10 @@
*/
public void _aload_3(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_3],
getLocalVariableName(pc, 3)
- })));
+ }));
writeNewLine();
}
@@ -151,10 +153,10 @@
*/
public void _aload(int pc, int index) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD],
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, true)
+ }));
writeNewLine();
}
@@ -164,11 +166,11 @@
public void _anewarray(int pc, int index, IConstantPoolEntry constantClass) {
dumpPcNumber(pc);
buffer
- .append(Messages.bind(Messages.classformat_anewarray, (new String[] {
+ .append(Messages.bind(Messages.classformat_anewarray, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ANEWARRAY],
Integer.toString(index),
returnConstantClassName(constantClass)
- })));
+ }));
writeNewLine();
}
@@ -195,10 +197,10 @@
*/
public void _astore_0(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_0],
getLocalVariableName(pc, 0)
- })));
+ }));
writeNewLine();
}
@@ -207,13 +209,17 @@
*/
public void _astore_1(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_1],
getLocalVariableName(pc, 1)
- })));
+ }));
writeNewLine();
}
private String getLocalVariableName(int pc, int index) {
+ return getLocalVariableName(pc, index, false);
+ }
+
+ private String getLocalVariableName(int pc, int index, boolean showIndex) {
int nextPC = pc + 1;
switch(index) {
case 0 :
@@ -229,11 +235,20 @@
final ILocalVariableTableEntry entry = this.localVariableTableEntries[i];
final int startPC = entry.getStartPC();
if (entry.getIndex() == index && (startPC <= nextPC) && ((startPC + entry.getLength()) > nextPC)) {
- return new String(entry.getName());
+ final StringBuffer stringBuffer = new StringBuffer();
+ if (showIndex) {
+ stringBuffer.append(' ').append(index);
+ }
+ stringBuffer.append(' ').append('[').append(entry.getName()).append(']');
+ return String.valueOf(stringBuffer);
}
}
- String localVariableName = Messages.bind(Messages.disassembler_localvariablename, (new String[] {Integer.toString(index)}));
- return localVariableName;
+ if (showIndex) {
+ final StringBuffer stringBuffer = new StringBuffer();
+ stringBuffer.append(' ').append(index);
+ return String.valueOf(stringBuffer);
+ }
+ return EMPTY_LOCAL_NAME;
}
/**
@@ -241,10 +256,10 @@
*/
public void _astore_2(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_2],
getLocalVariableName(pc, 2)
- })));
+ }));
writeNewLine();
}
@@ -253,10 +268,10 @@
*/
public void _astore_3(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_3],
getLocalVariableName(pc, 3)
- })));
+ }));
writeNewLine();
}
@@ -265,10 +280,10 @@
*/
public void _astore(int pc, int index) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE],
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, true)
+ }));
writeNewLine();
}
@@ -334,11 +349,11 @@
public void _checkcast(int pc, int index, IConstantPoolEntry constantClass) {
dumpPcNumber(pc);
buffer
- .append(Messages.bind(Messages.classformat_checkcast, (new String[] {
+ .append(Messages.bind(Messages.classformat_checkcast, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.CHECKCAST],
Integer.toString(index),
returnConstantClassName(constantClass)
- })));
+ }));
writeNewLine();
}
@@ -446,10 +461,10 @@
*/
public void _dload_0(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load,new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_0],
getLocalVariableName(pc, 0)
- })));
+ }));
writeNewLine();
}
@@ -458,10 +473,10 @@
*/
public void _dload_1(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_1],
getLocalVariableName(pc, 1)
- })));
+ }));
writeNewLine();
}
@@ -470,10 +485,10 @@
*/
public void _dload_2(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_2],
getLocalVariableName(pc, 2)
- })));
+ }));
writeNewLine();
}
@@ -482,10 +497,10 @@
*/
public void _dload_3(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_3],
getLocalVariableName(pc, 3)
- })));
+ }));
writeNewLine();
}
@@ -494,10 +509,10 @@
*/
public void _dload(int pc, int index) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD],
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, true)
+ }));
writeNewLine();
}
@@ -542,10 +557,10 @@
*/
public void _dstore_0(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_0],
getLocalVariableName(pc, 0)
- })));
+ }));
writeNewLine();
}
@@ -554,10 +569,10 @@
*/
public void _dstore_1(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_1],
getLocalVariableName(pc, 1)
- })));
+ }));
writeNewLine();
}
@@ -566,10 +581,10 @@
*/
public void _dstore_2(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_2],
getLocalVariableName(pc, 2)
- })));
+ }));
writeNewLine();
}
@@ -578,10 +593,10 @@
*/
public void _dstore_3(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_3],
getLocalVariableName(pc, 3)
- })));
+ }));
writeNewLine();
}
@@ -590,10 +605,10 @@
*/
public void _dstore(int pc, int index) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE],
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, true)
+ }));
writeNewLine();
}
@@ -773,10 +788,10 @@
*/
public void _fload_0(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_0],
getLocalVariableName(pc, 0)
- })));
+ }));
writeNewLine();
}
@@ -785,10 +800,10 @@
*/
public void _fload_1(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_1],
getLocalVariableName(pc, 1)
- })));
+ }));
writeNewLine();
}
@@ -797,10 +812,10 @@
*/
public void _fload_2(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_2],
getLocalVariableName(pc, 2)
- })));
+ }));
writeNewLine();
}
@@ -809,10 +824,10 @@
*/
public void _fload_3(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_3],
getLocalVariableName(pc, 3)
- })));
+ }));
writeNewLine();
}
@@ -821,10 +836,10 @@
*/
public void _fload(int pc, int index) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD],
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, true)
+ }));
writeNewLine();
}
@@ -869,10 +884,10 @@
*/
public void _fstore_0(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store,new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_0],
getLocalVariableName(pc, 0)
- })));
+ }));
writeNewLine();
}
@@ -881,10 +896,10 @@
*/
public void _fstore_1(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_1],
getLocalVariableName(pc, 1)
- })));
+ }));
writeNewLine();
}
@@ -893,10 +908,10 @@
*/
public void _fstore_2(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_2],
getLocalVariableName(pc, 2)
- })));
+ }));
writeNewLine();
}
@@ -905,10 +920,10 @@
*/
public void _fstore_3(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_3],
getLocalVariableName(pc, 3)
- })));
+ }));
writeNewLine();
}
@@ -917,10 +932,10 @@
*/
public void _fstore(int pc, int index) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE],
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, true)
+ }));
writeNewLine();
}
@@ -938,13 +953,13 @@
*/
public void _getfield(int pc, int index, IConstantPoolEntry constantFieldref) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_getfield, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_getfield, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GETFIELD],
Integer.toString(index),
returnDeclaringClassName(constantFieldref),
new String(constantFieldref.getFieldName()),
- new String(constantFieldref.getFieldDescriptor())
- })));
+ returnClassName(Signature.toCharArray(constantFieldref.getFieldDescriptor()))
+ }));
writeNewLine();
}
@@ -953,13 +968,13 @@
*/
public void _getstatic(int pc, int index, IConstantPoolEntry constantFieldref) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_getstatic, (new String[] {
- OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GETSTATIC],
- Integer.toString(index),
- returnDeclaringClassName(constantFieldref),
- new String(constantFieldref.getFieldName()),
- new String(constantFieldref.getFieldDescriptor())
- })));
+ buffer.append(Messages.bind(Messages.classformat_getstatic, new String[] {
+ OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GETSTATIC],
+ Integer.toString(index),
+ returnDeclaringClassName(constantFieldref),
+ new String(constantFieldref.getFieldName()),
+ returnClassName(Signature.toCharArray(constantFieldref.getFieldDescriptor()))
+ }));
writeNewLine();
}
@@ -1328,12 +1343,12 @@
*/
public void _iinc(int pc, int index, int _const) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_iinc, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_iinc, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IINC],
Integer.toString(index),
Integer.toString(_const),
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, false)
+ }));
writeNewLine();
}
@@ -1342,10 +1357,10 @@
*/
public void _iload_0(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_0],
getLocalVariableName(pc, 0)
- })));
+ }));
writeNewLine();
}
@@ -1354,10 +1369,10 @@
*/
public void _iload_1(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_1],
getLocalVariableName(pc, 1)
- })));
+ }));
writeNewLine();
}
@@ -1366,10 +1381,10 @@
*/
public void _iload_2(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_2],
getLocalVariableName(pc, 2)
- })));
+ }));
writeNewLine();
}
@@ -1378,10 +1393,10 @@
*/
public void _iload_3(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_3],
getLocalVariableName(pc, 3)
- })));
+ }));
writeNewLine();
}
@@ -1390,10 +1405,10 @@
*/
public void _iload(int pc, int index) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD],
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, true)
+ }));
writeNewLine();
}
@@ -1420,11 +1435,11 @@
*/
public void _instanceof(int pc, int index, IConstantPoolEntry constantClass) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_instanceof, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_instanceof, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INSTANCEOF],
Integer.toString(index),
returnConstantClassName(constantClass)
- })));
+ }));
writeNewLine();
}
@@ -1438,27 +1453,17 @@
IConstantPoolEntry constantInterfaceMethodref) {
dumpPcNumber(pc);
- if (isCompact()) {
- buffer.append(Messages.bind(Messages.classformat_invokeinterface_compact, (new String[] {
- OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEINTERFACE],
- Integer.toString(index),
- Integer.toString(nargs),
- Util.toString(
- constantInterfaceMethodref.getClassName(),
- constantInterfaceMethodref.getMethodName(),
- constantInterfaceMethodref.getMethodDescriptor(),
- true)
- })));
- } else {
- buffer.append(Messages.bind(Messages.classformat_invokeinterface, (new String[] {
- OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEINTERFACE],
- Integer.toString(index),
- Integer.toString(nargs),
- returnDeclaringClassName(constantInterfaceMethodref),
- new String(constantInterfaceMethodref.getMethodName()),
- new String(constantInterfaceMethodref.getMethodDescriptor()),
- })));
- }
+ buffer.append(Messages.bind(Messages.classformat_invokeinterface, new String[] {
+ OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEINTERFACE],
+ Integer.toString(index),
+ Integer.toString(nargs),
+ Util.toString(
+ constantInterfaceMethodref.getClassName(),
+ constantInterfaceMethodref.getMethodName(),
+ constantInterfaceMethodref.getMethodDescriptor(),
+ true,
+ isCompact())
+ }));
writeNewLine();
}
@@ -1467,25 +1472,16 @@
*/
public void _invokespecial(int pc, int index, IConstantPoolEntry constantMethodref) {
dumpPcNumber(pc);
- if (isCompact()) {
- buffer.append(Messages.bind(Messages.classformat_invokespecial_compact, (new String[] {
- OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESPECIAL],
- Integer.toString(index),
- Util.toString(
- constantMethodref.getClassName(),
- constantMethodref.getMethodName(),
- constantMethodref.getMethodDescriptor(),
- true)
- })));
- } else {
- buffer.append(Messages.bind(Messages.classformat_invokespecial, (new String[] {
- OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESPECIAL],
- Integer.toString(index),
- returnDeclaringClassName(constantMethodref),
- new String(constantMethodref.getMethodName()),
- new String(constantMethodref.getMethodDescriptor()),
- })));
- }
+ buffer.append(Messages.bind(Messages.classformat_invokespecial, new String[] {
+ OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESPECIAL],
+ Integer.toString(index),
+ Util.toString(
+ constantMethodref.getClassName(),
+ constantMethodref.getMethodName(),
+ constantMethodref.getMethodDescriptor(),
+ true,
+ isCompact())
+ }));
writeNewLine();
}
@@ -1494,25 +1490,16 @@
*/
public void _invokestatic(int pc, int index, IConstantPoolEntry constantMethodref) {
dumpPcNumber(pc);
- if (isCompact()) {
- buffer.append(Messages.bind(Messages.classformat_invokestatic_compact, (new String[] {
- OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESTATIC],
- Integer.toString(index),
- Util.toString(
- constantMethodref.getClassName(),
- constantMethodref.getMethodName(),
- constantMethodref.getMethodDescriptor(),
- true)
- })));
- } else {
- buffer.append(Messages.bind(Messages.classformat_invokestatic, (new String[] {
- OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESTATIC],
- Integer.toString(index),
- returnDeclaringClassName(constantMethodref),
- new String(constantMethodref.getMethodName()),
- new String(constantMethodref.getMethodDescriptor()),
- })));
- }
+ buffer.append(Messages.bind(Messages.classformat_invokestatic, new String[] {
+ OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESTATIC],
+ Integer.toString(index),
+ Util.toString(
+ constantMethodref.getClassName(),
+ constantMethodref.getMethodName(),
+ constantMethodref.getMethodDescriptor(),
+ true,
+ isCompact())
+ }));
writeNewLine();
}
@@ -1521,25 +1508,16 @@
*/
public void _invokevirtual(int pc, int index, IConstantPoolEntry constantMethodref) {
dumpPcNumber(pc);
- if (isCompact()) {
- buffer.append(Messages.bind(Messages.classformat_invokevirtual_compact, (new String[] {
- OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEVIRTUAL],
- Integer.toString(index),
- Util.toString(
- constantMethodref.getClassName(),
- constantMethodref.getMethodName(),
- constantMethodref.getMethodDescriptor(),
- true)
- })));
- } else {
- buffer.append(Messages.bind(Messages.classformat_invokevirtual, (new String[] {
- OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEVIRTUAL],
- Integer.toString(index),
- returnDeclaringClassName(constantMethodref),
- new String(constantMethodref.getMethodName()),
- new String(constantMethodref.getMethodDescriptor()),
- })));
- }
+ buffer.append(Messages.bind(Messages.classformat_invokevirtual,new String[] {
+ OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEVIRTUAL],
+ Integer.toString(index),
+ Util.toString(
+ constantMethodref.getClassName(),
+ constantMethodref.getMethodName(),
+ constantMethodref.getMethodDescriptor(),
+ true,
+ isCompact())
+ }));
writeNewLine();
}
@@ -1593,10 +1571,10 @@
*/
public void _istore_0(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_0],
getLocalVariableName(pc, 0)
- })));
+ }));
writeNewLine();
}
@@ -1605,10 +1583,10 @@
*/
public void _istore_1(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_1],
getLocalVariableName(pc, 1)
- })));
+ }));
writeNewLine();
}
@@ -1617,10 +1595,10 @@
*/
public void _istore_2(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_2],
getLocalVariableName(pc, 2)
- })));
+ }));
writeNewLine();
}
@@ -1629,10 +1607,10 @@
*/
public void _istore_3(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_3],
getLocalVariableName(pc, 3)
- })));
+ }));
writeNewLine();
}
@@ -1641,10 +1619,10 @@
*/
public void _istore(int pc, int index) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE],
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, true)
+ }));
writeNewLine();
}
@@ -1794,32 +1772,32 @@
dumpPcNumber(pc);
switch (constantPoolEntry.getKind()) {
case IConstantPoolConstant.CONSTANT_Float :
- buffer.append(Messages.bind(Messages.classformat_ldc_w_float, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_ldc_w_float, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
Integer.toString(index),
Float.toString(constantPoolEntry.getFloatValue())
- })));
+ }));
break;
case IConstantPoolConstant.CONSTANT_Integer :
- buffer.append(Messages.bind(Messages.classformat_ldc_w_integer, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_ldc_w_integer, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
Integer.toString(index),
Integer.toString(constantPoolEntry.getIntegerValue())
- })));
+ }));
break;
case IConstantPoolConstant.CONSTANT_String :
- buffer.append(Messages.bind(Messages.classformat_ldc_w_string, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_ldc_w_string, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
Integer.toString(index),
constantPoolEntry.getStringValue()
- })));
+ }));
break;
case IConstantPoolConstant.CONSTANT_Class :
- buffer.append(Messages.bind(Messages.classformat_ldc_w_class, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_ldc_w_class, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
Integer.toString(index),
returnConstantClassName(constantPoolEntry)
- })));
+ }));
}
writeNewLine();
}
@@ -1831,32 +1809,32 @@
dumpPcNumber(pc);
switch (constantPoolEntry.getKind()) {
case IConstantPoolConstant.CONSTANT_Float :
- buffer.append(Messages.bind(Messages.classformat_ldc_w_float, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_ldc_w_float, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
Integer.toString(index),
Float.toString(constantPoolEntry.getFloatValue())
- })));
+ }));
break;
case IConstantPoolConstant.CONSTANT_Integer :
- buffer.append(Messages.bind(Messages.classformat_ldc_w_integer, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_ldc_w_integer, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
Integer.toString(index),
Integer.toString(constantPoolEntry.getIntegerValue())
- })));
+ }));
break;
case IConstantPoolConstant.CONSTANT_String :
- buffer.append(Messages.bind(Messages.classformat_ldc_w_string, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_ldc_w_string, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
Integer.toString(index),
constantPoolEntry.getStringValue()
- })));
+ }));
break;
case IConstantPoolConstant.CONSTANT_Class :
- buffer.append(Messages.bind(Messages.classformat_ldc_w_class, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_ldc_w_class, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
Integer.toString(index),
returnConstantClassName(constantPoolEntry)
- })));
+ }));
}
writeNewLine();
}
@@ -1868,18 +1846,18 @@
dumpPcNumber(pc);
switch (constantPoolEntry.getKind()) {
case IConstantPoolConstant.CONSTANT_Long :
- buffer.append(Messages.bind(Messages.classformat_ldc2_w_long, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_ldc2_w_long, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC2_W],
Integer.toString(index),
Long.toString(constantPoolEntry.getLongValue())
- })));
+ }));
break;
case IConstantPoolConstant.CONSTANT_Double :
- buffer.append(Messages.bind(Messages.classformat_ldc2_w_double, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_ldc2_w_double, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC2_W],
Integer.toString(index),
Double.toString(constantPoolEntry.getDoubleValue())
- })));
+ }));
}
writeNewLine();
}
@@ -1898,10 +1876,10 @@
*/
public void _lload_0(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_0],
getLocalVariableName(pc, 0)
- })));
+ }));
writeNewLine();
}
@@ -1910,10 +1888,10 @@
*/
public void _lload_1(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_1],
getLocalVariableName(pc, 1)
- })));
+ }));
writeNewLine();
}
@@ -1922,10 +1900,10 @@
*/
public void _lload_2(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_2],
getLocalVariableName(pc, 2)
- })));
+ }));
writeNewLine();
}
@@ -1934,10 +1912,10 @@
*/
public void _lload_3(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_3],
getLocalVariableName(pc, 3)
- })));
+ }));
writeNewLine();
}
@@ -1946,10 +1924,10 @@
*/
public void _lload(int pc, int index) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_load, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD],
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, true)
+ }));
writeNewLine();
}
@@ -2041,10 +2019,10 @@
*/
public void _lstore_0(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_0],
getLocalVariableName(pc, 0)
- })));
+ }));
writeNewLine();
}
@@ -2053,10 +2031,10 @@
*/
public void _lstore_1(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_1],
getLocalVariableName(pc, 1)
- })));
+ }));
writeNewLine();
}
@@ -2065,10 +2043,10 @@
*/
public void _lstore_2(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_2],
getLocalVariableName(pc, 2)
- })));
+ }));
writeNewLine();
}
@@ -2077,10 +2055,10 @@
*/
public void _lstore_3(int pc) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_3],
getLocalVariableName(pc, 3)
- })));
+ }));
writeNewLine();
}
@@ -2089,10 +2067,10 @@
*/
public void _lstore(int pc, int index) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_store, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE],
- getLocalVariableName(pc, index)
- })));
+ getLocalVariableName(pc, index, true)
+ }));
writeNewLine();
}
@@ -2150,12 +2128,12 @@
int dimensions,
IConstantPoolEntry constantClass) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_multianewarray, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_multianewarray, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.MULTIANEWARRAY],
Integer.toString(index),
returnConstantClassName(constantClass),
appendDimensions(dimensions)
- })));
+ }));
writeNewLine();
}
@@ -2164,11 +2142,11 @@
*/
public void _new(int pc, int index, IConstantPoolEntry constantClass) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_new, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_new, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEW],
Integer.toString(index),
returnConstantClassName(constantClass)
- })));
+ }));
writeNewLine();
}
@@ -2179,52 +2157,52 @@
dumpPcNumber(pc);
switch(atype) {
case T_BOOLEAN :
- this.buffer.append(Messages.bind(Messages.classformat_newarray_boolean, (new String[] {
+ this.buffer.append(Messages.bind(Messages.classformat_newarray_boolean, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
Integer.toString(atype)
- })));
+ }));
break;
case T_CHAR :
- this.buffer.append(Messages.bind(Messages.classformat_newarray_char, (new String[] {
+ this.buffer.append(Messages.bind(Messages.classformat_newarray_char, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
Integer.toString(atype)
- })));
+ }));
break;
case T_FLOAT :
- this.buffer.append(Messages.bind(Messages.classformat_newarray_float, (new String[] {
+ this.buffer.append(Messages.bind(Messages.classformat_newarray_float, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
Integer.toString(atype)
- })));
+ }));
break;
case T_DOUBLE :
- this.buffer.append(Messages.bind(Messages.classformat_newarray_double, (new String[] {
+ this.buffer.append(Messages.bind(Messages.classformat_newarray_double, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
Integer.toString(atype)
- })));
+ }));
break;
case T_BYTE :
- this.buffer.append(Messages.bind(Messages.classformat_newarray_byte, (new String[] {
+ this.buffer.append(Messages.bind(Messages.classformat_newarray_byte, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
Integer.toString(atype)
- })));
+ }));
break;
case T_SHORT :
- this.buffer.append(Messages.bind(Messages.classformat_newarray_short, (new String[] {
+ this.buffer.append(Messages.bind(Messages.classformat_newarray_short, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
Integer.toString(atype)
- })));
+ }));
break;
case T_INT :
- this.buffer.append(Messages.bind(Messages.classformat_newarray_int, (new String[] {
+ this.buffer.append(Messages.bind(Messages.classformat_newarray_int, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
Integer.toString(atype)
- })));
+ }));
break;
case T_LONG :
- this.buffer.append(Messages.bind(Messages.classformat_newarray_long, (new String[] {
+ this.buffer.append(Messages.bind(Messages.classformat_newarray_long, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
Integer.toString(atype)
- })));
+ }));
}
writeNewLine();
}
@@ -2261,13 +2239,13 @@
*/
public void _putfield(int pc, int index, IConstantPoolEntry constantFieldref) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_putfield, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_putfield, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.PUTFIELD],
Integer.toString(index),
returnDeclaringClassName(constantFieldref),
new String(constantFieldref.getFieldName()),
- new String(constantFieldref.getFieldDescriptor())
- })));
+ returnClassName(Signature.toCharArray(constantFieldref.getFieldDescriptor()))
+ }));
writeNewLine();
}
@@ -2276,13 +2254,13 @@
*/
public void _putstatic(int pc, int index, IConstantPoolEntry constantFieldref) {
dumpPcNumber(pc);
- buffer.append(Messages.bind(Messages.classformat_putstatic, (new String[] {
+ buffer.append(Messages.bind(Messages.classformat_putstatic, new String[] {
OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.PUTSTATIC],
Integer.toString(index),
returnDeclaringClassName(constantFieldref),
new String(constantFieldref.getFieldName()),
- new String(constantFieldref.getFieldDescriptor())
- })));
+ returnClassName(Signature.toCharArray(constantFieldref.getFieldDescriptor()))
+ }));
writeNewLine();
}
@@ -2464,6 +2442,9 @@
private String returnConstantClassName(IConstantPoolEntry constantClass) {
char[] classInfoName = constantClass.getClassInfoName();
+ return returnClassName(classInfoName);
+ }
+ private String returnClassName(char[] classInfoName) {
if (classInfoName.length == 0) {
return EMPTY_CLASS_NAME;
} else if (isCompact()) {
@@ -2471,22 +2452,14 @@
if (lastIndexOfSlash != -1) {
return new String(classInfoName, lastIndexOfSlash + 1, classInfoName.length - lastIndexOfSlash - 1);
}
- return new String(classInfoName);
- } else {
- return new String(classInfoName);
}
+ CharOperation.replace(classInfoName, '/', '.');
+ return new String(classInfoName);
}
private String returnDeclaringClassName(IConstantPoolEntry constantRef) {
- if (isCompact()) {
- char[] className = constantRef.getClassName();
- int lastIndexOfSlash = CharOperation.lastIndexOf('/', className);
- if (lastIndexOfSlash != -1) {
- return new String(className, lastIndexOfSlash + 1, className.length - lastIndexOfSlash - 1);
- }
- return new String(constantRef.getClassName());
- }
- return new String(constantRef.getClassName());
+ final char[] className = constantRef.getClassName();
+ return returnClassName(className);
}
private void writeNewLine() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
index ddf744c..1be2fa0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
@@ -39,6 +39,7 @@
*/
public class Disassembler extends ClassFileBytesDisassembler {
+ private static final String EMPTY_CLASS_NAME = "\"\""; //$NON-NLS-1$
private static final char[] ANY_EXCEPTION = Messages.classfileformat_anyexceptionhandler.toCharArray();
private static final String EMPTY_OUTPUT = ""; //$NON-NLS-1$
private static final String VERSION_UNKNOWN = "unknown";//$NON-NLS-1$
@@ -394,13 +395,13 @@
char[] exceptionName = exceptionNames[i];
CharOperation.replace(exceptionName, '/', '.');
buffer
- .append(exceptionName)
+ .append(returnClassName(exceptionName, '.', mode))
.append(Messages.disassembler_comma)
.append(Messages.disassembler_space);
}
char[] exceptionName = exceptionNames[length - 1];
CharOperation.replace(exceptionName, '/', '.');
- buffer.append(exceptionName);
+ buffer.append(returnClassName(exceptionName, '.', mode));
}
if (checkMode(mode, DETAILED)) {
if (annotationDefaultAttribute != null) {
@@ -578,7 +579,7 @@
if (superclassName != null) {
buffer.append(" extends "); //$NON-NLS-1$
CharOperation.replace(superclassName, '/', '.');
- buffer.append(superclassName);
+ buffer.append(returnClassName(superclassName, '.', mode));
}
char[][] superclassInterfaces = classFileReader.getInterfaceNames();
int length = superclassInterfaces.length;
@@ -588,13 +589,13 @@
char[] superinterface = superclassInterfaces[i];
CharOperation.replace(superinterface, '/', '.');
buffer
- .append(superinterface)
+ .append(returnClassName(superinterface, '.', mode))
.append(Messages.disassembler_comma)
.append(Messages.disassembler_space);
}
char[] superinterface = superclassInterfaces[length - 1];
CharOperation.replace(superinterface, '/', '.');
- buffer.append(superinterface);
+ buffer.append(returnClassName(superinterface, '.', mode));
}
buffer.append(Messages.bind(Messages.disassembler_opentypedeclaration));
if (checkMode(mode, SYSTEM)) {
@@ -743,13 +744,15 @@
int index= localVariableTableEntry.getIndex();
int startPC = localVariableTableEntry.getStartPC();
int length = localVariableTableEntry.getLength();
+ final char[] typeName = Signature.toCharArray(localVariableTableEntry.getDescriptor());
+ CharOperation.replace(typeName, '/', '.');
buffer.append(Messages.bind(Messages.classfileformat_localvariabletableentry,
new String[] {
Integer.toString(startPC),
Integer.toString(startPC + length),
new String(localVariableTableEntry.getName()),
Integer.toString(index),
- new String(localVariableTableEntry.getDescriptor())
+ new String(returnClassName(typeName, '.', mode))
}));
writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute + 1);
}
@@ -757,13 +760,15 @@
int index= localVariableTableEntry.getIndex();
int startPC = localVariableTableEntry.getStartPC();
int length = localVariableTableEntry.getLength();
+ final char[] typeName = Signature.toCharArray(localVariableTableEntry.getDescriptor());
+ CharOperation.replace(typeName, '/', '.');
buffer.append(Messages.bind(Messages.classfileformat_localvariabletableentry,
new String[] {
Integer.toString(startPC),
Integer.toString(startPC + length),
new String(localVariableTableEntry.getName()),
Integer.toString(index),
- new String(localVariableTableEntry.getDescriptor())
+ new String(returnClassName(typeName, '.', mode))
}));
}
ILocalVariableTypeTableAttribute localVariableTypeAttribute= getLocalVariableTypeAttribute(codeAttribute);
@@ -779,13 +784,15 @@
int index= localVariableTypeTableEntry.getIndex();
int startPC = localVariableTypeTableEntry.getStartPC();
int length = localVariableTypeTableEntry.getLength();
+ final char[] typeName = Signature.toCharArray(localVariableTypeTableEntry.getSignature());
+ CharOperation.replace(typeName, '/', '.');
buffer.append(Messages.bind(Messages.classfileformat_localvariabletableentry,
new String[] {
Integer.toString(startPC),
Integer.toString(startPC + length),
new String(localVariableTypeTableEntry.getName()),
Integer.toString(index),
- new String(localVariableTypeTableEntry.getSignature())
+ new String(returnClassName(typeName, '.', mode))
}));
writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute + 1);
}
@@ -793,13 +800,15 @@
int index= localVariableTypeTableEntry.getIndex();
int startPC = localVariableTypeTableEntry.getStartPC();
int length = localVariableTypeTableEntry.getLength();
+ final char[] typeName = Signature.toCharArray(localVariableTypeTableEntry.getSignature());
+ CharOperation.replace(typeName, '/', '.');
buffer.append(Messages.bind(Messages.classfileformat_localvariabletableentry,
new String[] {
Integer.toString(startPC),
Integer.toString(startPC + length),
new String(localVariableTypeTableEntry.getName()),
Integer.toString(index),
- new String(localVariableTypeTableEntry.getSignature())
+ new String(returnClassName(typeName, '.', mode))
}));
}
}
@@ -831,12 +840,13 @@
buffer.append(
Messages.bind(Messages.disassembler_constantpool_fieldref,
new String[] {
- Integer.toString(i),
- Integer.toString(constantPoolEntry.getClassIndex()),
- Integer.toString(constantPoolEntry.getNameAndTypeIndex()),
- new String(constantPoolEntry.getClassName()),
- new String(constantPoolEntry.getFieldName()),
- new String(constantPoolEntry.getFieldDescriptor())}));
+ Integer.toString(i),
+ Integer.toString(constantPoolEntry.getClassIndex()),
+ Integer.toString(constantPoolEntry.getNameAndTypeIndex()),
+ new String(constantPoolEntry.getClassName()),
+ new String(constantPoolEntry.getFieldName()),
+ new String(constantPoolEntry.getFieldDescriptor())
+ }));
break;
case IConstantPoolConstant.CONSTANT_Float :
buffer.append(
@@ -849,8 +859,8 @@
buffer.append(
Messages.bind(Messages.disassembler_constantpool_integer,
new String[] {
- Integer.toString(i),
- Integer.toString(constantPoolEntry.getIntegerValue())}));
+ Integer.toString(i),
+ Integer.toString(constantPoolEntry.getIntegerValue())}));
break;
case IConstantPoolConstant.CONSTANT_InterfaceMethodref :
buffer.append(
@@ -1438,6 +1448,24 @@
return (mode & flag) != 0;
}
+ private boolean isCompact(int mode) {
+ return (mode & ClassFileBytesDisassembler.COMPACT) != 0;
+ }
+
+ private String returnClassName(char[] classInfoName, char separator, int mode) {
+ if (classInfoName.length == 0) {
+ return EMPTY_CLASS_NAME;
+ } else if (isCompact(mode)) {
+ int lastIndexOfSlash = CharOperation.lastIndexOf(separator, classInfoName);
+ if (lastIndexOfSlash != -1) {
+ return new String(classInfoName, lastIndexOfSlash + 1, classInfoName.length - lastIndexOfSlash - 1);
+ }
+ return new String(classInfoName);
+ } else {
+ return new String(classInfoName);
+ }
+ }
+
private void writeNewLine(StringBuffer buffer, String lineSeparator, int tabNumber) {
buffer.append(lineSeparator);
dumpTab(tabNumber, buffer);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyKind.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyKind.java
index a145a5a..d2a788a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyKind.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyKind.java
@@ -12,20 +12,22 @@
public class KeyKind extends BindingKeyParser {
- public static final int F_TYPE = 0x0001;
- public static final int F_METHOD = 0x0010;
- public static final int F_FIELD = 0x0011;
- public static final int F_TYPE_PARAMETER = 0x0100;
- public static final int F_LOCAL_VAR = 0x0101;
- public static final int F_MEMBER = 0x0110;
- public static final int F_LOCAL = 0x0111;
- public static final int F_PARAMETERIZED_TYPE = 0x1000;
- public static final int F_RAW_TYPE = 0x1001;
- public static final int F_WILDCARD_TYPE = 0x1010;
- public static final int F_PARAMETERIZED_METHOD = 0x1011;
- public static final int F_CAPTURE = 0x1111;
+ public static final int F_TYPE = 0x00001;
+ public static final int F_METHOD = 0x00010;
+ public static final int F_FIELD = 0x00011;
+ public static final int F_TYPE_PARAMETER = 0x00100;
+ public static final int F_LOCAL_VAR = 0x00101;
+ public static final int F_MEMBER = 0x00110;
+ public static final int F_LOCAL = 0x00111;
+ public static final int F_PARAMETERIZED_TYPE = 0x01000;
+ public static final int F_RAW_TYPE = 0x01001;
+ public static final int F_WILDCARD_TYPE = 0x01010;
+ public static final int F_PARAMETERIZED_METHOD = 0x01011;
+ public static final int F_CAPTURE = 0x01111;
+ public static final int F_CONSTRUCTOR = 0x10000;
public int flags = 0;
+ private KeyKind innerKeyKind;
public KeyKind(BindingKeyParser parser) {
super(parser);
@@ -34,8 +36,12 @@
public KeyKind(String key) {
super(key);
}
+
+ public void consumeBaseType(char[] baseTypeSig) {
+ this.flags |= F_TYPE;
+ }
- public void consumeCapture() {
+ public void consumeCapture(int position) {
this.flags |= F_CAPTURE;
}
@@ -57,15 +63,21 @@
public void consumeMethod(char[] selector, char[] signature) {
this.flags |= F_METHOD;
+ if (selector.length == 0)
+ this.flags |= F_CONSTRUCTOR;
}
- public void consumeParameterizedMethod() {
+ public void consumeParameterizedGenericMethod() {
this.flags |= F_PARAMETERIZED_METHOD;
}
public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
this.flags |= isRaw ? F_RAW_TYPE : F_PARAMETERIZED_TYPE;
}
+
+ public void consumeParser(BindingKeyParser parser) {
+ this.innerKeyKind = (KeyKind) parser;
+ }
public void consumeRawType() {
this.flags |= F_RAW_TYPE;
@@ -78,12 +90,16 @@
public void consumeTypeParameter(char[] typeParameterName) {
this.flags |= F_TYPE_PARAMETER;
}
+
+ public void consumeTypeWithCapture() {
+ this.flags = this.innerKeyKind.flags;
+ }
public void consumeWildCard(int kind) {
this.flags |= F_WILDCARD_TYPE;
}
public BindingKeyParser newParser() {
- return new BindingKeyParser(this);
+ return new KeyKind(this);
}
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyToSignature.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyToSignature.java
index c269c33..99ff0e2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyToSignature.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyToSignature.java
@@ -12,13 +12,14 @@
import java.util.ArrayList;
+import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
/*
* Converts a binding key into a signature
*/
-// TODO (jerome) handle methods and fields
public class KeyToSignature extends BindingKeyParser {
public static final int SIGNATURE = 0;
@@ -31,9 +32,11 @@
private ArrayList typeParameters = new ArrayList();
private int mainTypeStart = -1;
private int mainTypeEnd;
+ private int typeSigStart = -1;
public KeyToSignature(BindingKeyParser parser) {
super(parser);
+ this.kind = ((KeyToSignature) parser).kind;
}
public KeyToSignature(String key, int kind) {
@@ -45,8 +48,14 @@
this.signature.append(brakets);
}
- public void consumeCapture() {
- this.signature.append('!');
+ public void consumeBaseType(char[] baseTypeSig) {
+ this.typeSigStart = this.signature.length();
+ this.signature.append(baseTypeSig);
+ }
+
+ public void consumeCapture(int position) {
+ // behave as if it was a wildcard
+ this.signature = ((KeyToSignature) this.arguments.get(0)).signature;
}
public void consumeLocalType(char[] uniqueKey) {
@@ -75,6 +84,92 @@
this.signature.append(pkgName);
}
+ public void consumeParameterizedGenericMethod() {
+ int typeParametersSize = this.arguments.size();
+ if (typeParametersSize > 0) {
+ int sigLength = this.signature.length();
+ char[] methodSignature = new char[sigLength];
+ this.signature.getChars(0, sigLength, methodSignature, 0);
+ char[][] typeParameterSigs = Signature.getTypeParameters(methodSignature);
+ if (typeParameterSigs.length != typeParametersSize)
+ return;
+ this.signature = new StringBuffer();
+
+ // type parameters
+ for (int i = 0; i < typeParametersSize; i++)
+ typeParameterSigs[i] = CharOperation.concat(Signature.C_TYPE_VARIABLE,Signature.getTypeVariable(typeParameterSigs[i]), Signature.C_SEMICOLON);
+ int paramStart = CharOperation.indexOf(Signature.C_PARAM_START, methodSignature);
+ char[] typeParametersString = CharOperation.subarray(methodSignature, 0, paramStart);
+ this.signature.append(typeParametersString);
+
+ // substitute parameters
+ this.signature.append(Signature.C_PARAM_START);
+ char[][] parameters = Signature.getParameterTypes(methodSignature);
+ for (int i = 0, parametersLength = parameters.length; i < parametersLength; i++)
+ substitute(parameters[i], typeParameterSigs, typeParametersSize);
+ this.signature.append(Signature.C_PARAM_END);
+
+ // substitute return type
+ char[] returnType = Signature.getReturnType(methodSignature);
+ substitute(returnType, typeParameterSigs, typeParametersSize);
+
+ // substitute exceptions
+ char[][] exceptions = Signature.getThrownExceptionTypes(methodSignature);
+ for (int i = 0, exceptionsLength = exceptions.length; i < exceptionsLength; i++) {
+ this.signature.append(Signature.C_EXCEPTION_START);
+ substitute(exceptions[i], typeParameterSigs, typeParametersSize);
+ }
+
+ }
+ }
+
+ /*
+ * Substitutes the type variables referenced in the given parameter (a parameterized type signature) with the corresponding
+ * type argument.
+ * Appends the given parameter if it is not a parameterized type signature.
+ */
+ private void substitute(char[] parameter, char[][] typeParameterSigs, int typeParametersLength) {
+ for (int i = 0; i < typeParametersLength; i++) {
+ if (CharOperation.equals(parameter, typeParameterSigs[i])) {
+ String typeArgument = ((KeyToSignature) this.arguments.get(i)).signature.toString();
+ this.signature.append(typeArgument);
+ return;
+ }
+ }
+ int genericStart = CharOperation.indexOf(Signature.C_GENERIC_START, parameter);
+ if (genericStart > -1) {
+ this.signature.append(CharOperation.subarray(parameter, 0, genericStart));
+ char[][] parameters = Signature.getTypeArguments(parameter);
+ this.signature.append(Signature.C_GENERIC_START);
+ for (int j = 0, paramsLength = parameters.length; j < paramsLength; j++)
+ substitute(parameters[j], typeParameterSigs, typeParametersLength);
+ this.signature.append(Signature.C_GENERIC_END);
+ this.signature.append(Signature.C_SEMICOLON);
+ } else {
+ // handle array, wildcard and capture
+ int index = 0;
+ int length = parameter.length;
+ loop: while (index < length) {
+ char current = parameter[index];
+ switch (current) {
+ case Signature.C_CAPTURE:
+ case Signature.C_EXTENDS:
+ case Signature.C_SUPER:
+ case Signature.C_ARRAY:
+ this.signature.append(current);
+ index++;
+ break;
+ default:
+ break loop;
+ }
+ }
+ if (index > 0)
+ substitute(CharOperation.subarray(parameter, index, length), typeParameterSigs, typeParametersLength);
+ else
+ this.signature.append(parameter);
+ }
+ }
+
public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
if (simpleTypeName != null) {
// member type
@@ -85,7 +180,7 @@
this.signature.append('<');
int length = this.arguments.size();
for (int i = 0; i < length; i++) {
- this.signature.append(this.arguments.get(i));
+ this.signature.append(((KeyToSignature) this.arguments.get(i)).signature);
}
this.signature.append('>');
if (this.kind != TYPE_ARGUMENTS)
@@ -94,10 +189,17 @@
}
public void consumeParser(BindingKeyParser parser) {
- this.arguments.add(((KeyToSignature) parser).signature);
+ this.arguments.add(parser);
+ }
+
+ public void consumeField(char[] fieldName) {
+ if (this.kind == SIGNATURE) {
+ this.signature = ((KeyToSignature) this.arguments.get(0)).signature;
+ }
}
public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
+ this.typeSigStart = this.signature.length();
this.signature.append('L');
this.signature.append(CharOperation.replaceOnCopy(fullyQualifiedName, '/', '.'));
}
@@ -112,21 +214,26 @@
}
public void consumeType() {
- int length = this.typeParameters.size();
- if (length > 0) {
- this.signature.append('<');
- for (int i = 0; i < length; i++) {
- this.signature.append('T');
- this.signature.append((char[]) this.typeParameters.get(i));
- this.signature.append(';');
- }
- this.signature.append('>');
- this.typeParameters = new ArrayList();
- }
// remove main type if needed
if (this.mainTypeStart != -1) {
this.signature.replace(this.mainTypeStart, this.mainTypeEnd, ""); //$NON-NLS-1$
}
+ // parameter types
+ int length = this.typeParameters.size();
+ if (length > 0) {
+ StringBuffer typeParametersSig = new StringBuffer();
+ typeParametersSig.append('<');
+ for (int i = 0; i < length; i++) {
+ char[] typeParameterSig = Signature.createTypeParameterSignature(
+ (char[]) this.typeParameters.get(i),
+ new char[][]{ ConstantPool.ObjectSignature });
+ typeParametersSig.append(typeParameterSig);
+ // TODO (jerome) add type parameter bounds in binding key
+ }
+ typeParametersSig.append('>');
+ this.signature.insert(this.typeSigStart, typeParametersSig);
+ this.typeParameters = new ArrayList();
+ }
this.signature.append(';');
}
@@ -134,23 +241,33 @@
this.typeParameters.add(typeParameterName);
}
- public void consumeTypeVariable(char[] typeVariableName) {
+ public void consumeTypeVariable(char[] position, char[] typeVariableName) {
this.signature = new StringBuffer();
this.signature.append('T');
this.signature.append(typeVariableName);
this.signature.append(';');
}
+ public void consumeTypeWithCapture() {
+ KeyToSignature keyToSignature = (KeyToSignature) this.arguments.get(0);
+ this.signature = keyToSignature.signature;
+ this.arguments = keyToSignature.arguments;
+ }
+
public void consumeWildCard(int wildCardKind) {
+ // don't put generic type in signature
+ this.signature = new StringBuffer();
switch (wildCardKind) {
case Wildcard.UNBOUND:
this.signature.append('*');
break;
case Wildcard.EXTENDS:
this.signature.append('+');
+ this.signature.append(((KeyToSignature) this.arguments.get(0)).signature);
break;
case Wildcard.SUPER:
this.signature.append('-');
+ this.signature.append(((KeyToSignature) this.arguments.get(0)).signature);
break;
default:
// malformed
@@ -162,7 +279,7 @@
int length = this.arguments.size();
String[] result = new String[length];
for (int i = 0; i < length; i++) {
- result[i] = ((StringBuffer) this.arguments.get(i)).toString();
+ result[i] = ((KeyToSignature) this.arguments.get(i)).signature.toString();
}
return result;
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
index 3678ae1..6b5bf2e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
@@ -158,12 +158,14 @@
public static String classpath_disabledInclusionExclusionPatterns;
public static String classpath_disabledMultipleOutputLocations;
public static String classpath_incompatibleLibraryJDKLevel;
+ public static String classpath_duplicateEntryExtraAttribute;
public static String file_notFound;
public static String file_badFormat;
public static String path_nullPath;
public static String path_mustBeAbsolute;
public static String cache_invalidLoadFactor;
public static String savedState_jobName;
+ public static String javamodel_initialization;
public static String restrictedAccess_project;
public static String restrictedAccess_library;
public static String convention_unit_nullName;
@@ -289,13 +291,9 @@
public static String classformat_new;
public static String classformat_iinc;
public static String classformat_invokespecial;
- public static String classformat_invokespecial_compact;
public static String classformat_invokeinterface;
- public static String classformat_invokeinterface_compact;
public static String classformat_invokestatic;
- public static String classformat_invokestatic_compact;
public static String classformat_invokevirtual;
- public static String classformat_invokevirtual_compact;
public static String classformat_getfield;
public static String classformat_getstatic;
public static String classformat_putstatic;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java
index a0d634e..c99113f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java
@@ -46,7 +46,7 @@
this.annotations = new IAnnotation[length];
for (int i = 0; i < length; i++) {
Annotation annotation = new Annotation(classFileBytes, constantPool, offset + readOffset);
- this.annotations[i++] = annotation;
+ this.annotations[i] = annotation;
this.readOffset += annotation.sizeInBytes();
}
} else {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
index dbd2607..6d9095f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
@@ -906,6 +906,9 @@
if (this.currentPosition > this.eofPosition)
return TokenNameEOF;
}
+ //little trick to get out in the middle of a source compuation
+ if (this.currentPosition > this.eofPosition)
+ return TokenNameEOF;
if (checkIfUnicode) {
isWhiteSpace = jumpOverUnicodeWhiteSpace();
offset = this.currentPosition - offset;
@@ -954,12 +957,7 @@
this.withoutUnicodePtr = 0;
}
}
- //little trick to get out in the middle of a source compuation
- if (this.currentPosition > this.eofPosition)
- return TokenNameEOF;
-
// ---------Identify the next token-------------
-
switch (this.currentCharacter) {
case '@' :
/* if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
@@ -2386,11 +2384,6 @@
}
this.commentPtr = -1; // reset comment stack
this.foundTaskCount = 0;
-
-// // if resetTo is used with being > than end.
-// if (begin > this.eofPosition) {
-// begin = this.eofPosition;
-// }
}
public final void scanEscapeCharacter() throws InvalidInputException {
@@ -3357,20 +3350,30 @@
this.containsAssertKeyword = false;
this.linePtr = -1;
}
-
/*
* Should be used if a parse (usually a diet parse) has already been performed on the unit,
* so as to get the already computed line end positions.
*/
-public final void setSource(CompilationResult compilationResult) {
- char[] contents = compilationResult.compilationUnit.getContents();
- setSource(contents);
+public final void setSource(char[] contents, CompilationResult compilationResult) {
+ if (contents == null) {
+ char[] cuContents = compilationResult.compilationUnit.getContents();
+ setSource(cuContents);
+ } else {
+ setSource(contents);
+ }
int[] lineSeparatorPositions = compilationResult.lineSeparatorPositions;
if (lineSeparatorPositions != null) {
this.lineEnds = lineSeparatorPositions;
this.linePtr = lineSeparatorPositions.length - 1;
}
}
+/*
+ * Should be used if a parse (usually a diet parse) has already been performed on the unit,
+ * so as to get the already computed line end positions.
+ */
+public final void setSource(CompilationResult compilationResult) {
+ setSource(null, compilationResult);
+}
public String toString() {
if (this.startPosition == this.source.length)
return "EOF\n\n" + new String(this.source); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
index e1bb0aa..2bdd34f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
@@ -16,11 +16,10 @@
import java.util.zip.ZipFile;
import org.eclipse.core.resources.*;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.dom.ASTNode;
@@ -841,6 +840,41 @@
}
/**
+ * Returns the line separator found in the given text.
+ * If it is null, or not found return the line delimitor for the given project.
+ * If the project is null, returns the line separator for the workspace.
+ * If still null, return the system line separator.
+ */
+ public static String getLineSeparator(String text, IJavaProject project) {
+ String lineSeparator = null;
+
+ // line delimiter in given text
+ if (text != null) {
+ lineSeparator = findLineSeparator(text.toCharArray());
+ if (lineSeparator != null)
+ return lineSeparator;
+ }
+
+ // line delimiter in project preference
+ IScopeContext[] scopeContext;
+ if (project != null) {
+ scopeContext= new IScopeContext[] { new ProjectScope(project.getProject()) };
+ lineSeparator= Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null, scopeContext);
+ if (lineSeparator != null)
+ return lineSeparator;
+ }
+
+ // line delimiter in workspace preference
+ scopeContext= new IScopeContext[] { new InstanceScope() };
+ lineSeparator = Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null, scopeContext);
+ if (lineSeparator != null)
+ return lineSeparator;
+
+ // system line delimiter
+ return org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR;
+ }
+
+ /**
* Returns the line separator used by the given buffer.
* Uses the given text if none found.
*
@@ -854,7 +888,7 @@
lineSeparator = findLineSeparator(text);
if (lineSeparator == null) {
// default to system line separator
- return org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR;
+ return getLineSeparator((String) null, (IJavaProject) null);
}
}
return lineSeparator;
@@ -1017,6 +1051,18 @@
}
/*
+ * Returns the declaring type signature of the element represented by the given binding key.
+ * Returns the signature of the element if it is a type.
+ *
+ * @return the declaring type signature
+ */
+ public static String getDeclaringTypeSignature(String key) {
+ KeyToSignature keyToSignature = new KeyToSignature(key, KeyToSignature.DECLARING_TYPE);
+ keyToSignature.parse();
+ return keyToSignature.signature.toString();
+ }
+
+ /*
* Appends to the given buffer the fully qualified name (as it appears in the source) of the given type
*/
private static void getFullyQualifiedName(Type type, StringBuffer buffer) {
@@ -1931,14 +1977,6 @@
}
return segs;
}
-
- /**
- * Converts a char[] to String.
- */
- public static String toString(char[] c) {
- return new String(c);
- }
-
/**
* Converts a char[][] to String, where segments are separated by '.'.
*/
@@ -1976,19 +2014,34 @@
}
return result;
}
- private static void appendArrayTypeSignature(char[] string, int start, StringBuffer buffer) {
+ private static void appendArrayTypeSignature(char[] string, int start, StringBuffer buffer, boolean compact) {
+ int length = string.length;
// need a minimum 2 char
- if (start >= string.length - 1) {
+ if (start >= length - 1) {
throw new IllegalArgumentException();
}
char c = string[start];
if (c != Signature.C_ARRAY) { //$NON-NLS-1$
throw new IllegalArgumentException();
}
- appendTypeSignature(string, start + 1, buffer);
- buffer.append('[').append(']');
+
+ int index = start;
+ c = string[++index];
+ while(c == Signature.C_ARRAY) {
+ // need a minimum 2 char
+ if (index >= length - 1) {
+ throw new IllegalArgumentException();
+ }
+ c = string[++index];
+ }
+
+ appendTypeSignature(string, index, buffer, compact);
+
+ for(int i = 0, dims = index - start; i < dims; i++) {
+ buffer.append('[').append(']');
+ }
}
- private static void appendClassTypeSignature(char[] string, int start, StringBuffer buffer) {
+ private static void appendClassTypeSignature(char[] string, int start, StringBuffer buffer, boolean compact) {
char c = string[start];
if (c != Signature.C_RESOLVED) {
return;
@@ -2002,12 +2055,13 @@
// all done
return;
case Signature.C_DOT :
+ case '/' :
// erase package prefix
- buffer.setLength(checkpoint);
- break;
- case '/' :
- // erase package prefix
- buffer.setLength(checkpoint);
+ if (compact) {
+ buffer.setLength(checkpoint);
+ } else {
+ buffer.append('.');
+ }
break;
case Signature.C_DOLLAR :
/**
@@ -2024,14 +2078,14 @@
p++;
}
}
- static void appendTypeSignature(char[] string, int start, StringBuffer buffer) {
+ static void appendTypeSignature(char[] string, int start, StringBuffer buffer, boolean compact) {
char c = string[start];
switch (c) {
case Signature.C_ARRAY :
- appendArrayTypeSignature(string, start, buffer);
+ appendArrayTypeSignature(string, start, buffer, compact);
break;
case Signature.C_RESOLVED :
- appendClassTypeSignature(string, start, buffer);
+ appendClassTypeSignature(string, start, buffer, compact);
break;
case Signature.C_TYPE_VARIABLE :
int e = Util.scanTypeVariableSignature(string, start);
@@ -2066,8 +2120,8 @@
break;
}
}
- public static String toString(char[] declaringClass, char[] methodName, char[] methodSignature, boolean includeReturnType) {
- boolean isConstructor = CharOperation.equals(methodName, INIT);
+ public static String toString(char[] declaringClass, char[] methodName, char[] methodSignature, boolean includeReturnType, boolean compact) {
+ final boolean isConstructor = CharOperation.equals(methodName, INIT);
int firstParen = CharOperation.indexOf(Signature.C_PARAM_START, methodSignature);
if (firstParen == -1) {
return ""; //$NON-NLS-1$
@@ -2075,25 +2129,28 @@
StringBuffer buffer = new StringBuffer(methodSignature.length + 10);
- if (!isConstructor) {
- // return type
- if (includeReturnType) {
- char[] rts = Signature.getReturnType(methodSignature);
- appendTypeSignature(rts, 0 , buffer);
- buffer.append(' ');
+ // decode declaring class name
+ // it can be either an array signature or a type signature
+ if (declaringClass.length > 0) {
+ char[] declaringClassSignature = null;
+ if (declaringClass[0] == Signature.C_ARRAY) {
+ CharOperation.replace(declaringClass, '/', '.');
+ declaringClassSignature = Signature.toCharArray(declaringClass);
+ } else {
+ CharOperation.replace(declaringClass, '/', '.');
+ declaringClassSignature = declaringClass;
+ }
+ int lastIndexOfSlash = CharOperation.lastIndexOf('.', declaringClassSignature);
+ if (compact && lastIndexOfSlash != -1) {
+ buffer.append(declaringClassSignature, lastIndexOfSlash + 1, declaringClassSignature.length - lastIndexOfSlash - 1);
+ } else {
+ buffer.append(declaringClassSignature);
}
}
-
+
// selector
- int lastIndexOfSlash = CharOperation.lastIndexOf('/', declaringClass);
- if (lastIndexOfSlash != -1) {
- buffer.append(declaringClass, lastIndexOfSlash + 1, declaringClass.length - lastIndexOfSlash - 1);
- } else {
- buffer.append(declaringClass);
- }
if (!isConstructor) {
buffer.append('.');
-
if (methodName != null) {
buffer.append(methodName);
}
@@ -2103,17 +2160,23 @@
buffer.append('(');
char[][] pts = Signature.getParameterTypes(methodSignature);
for (int i = 0, max = pts.length; i < max; i++) {
- if (i == max - 1) {
- appendTypeSignature(pts[i], 0 , buffer);
- } else {
- appendTypeSignature(pts[i], 0 , buffer);
- }
+ appendTypeSignature(pts[i], 0 , buffer, compact);
if (i != pts.length - 1) {
buffer.append(',');
buffer.append(' ');
}
}
buffer.append(')');
+
+ if (!isConstructor) {
+ buffer.append(" : "); //$NON-NLS-1$
+ // return type
+ if (includeReturnType) {
+ char[] rts = Signature.getReturnType(methodSignature);
+ appendTypeSignature(rts, 0 , buffer, compact);
+ buffer.append(' ');
+ }
+ }
return String.valueOf(buffer);
}
/*
@@ -2352,15 +2415,25 @@
* @exception IllegalArgumentException if this is not an array type signature
*/
public static int scanArrayTypeSignature(char[] string, int start) {
+ int length = string.length;
// need a minimum 2 char
- if (start >= string.length - 1) {
+ if (start >= length - 1) {
throw new IllegalArgumentException();
}
char c = string[start];
if (c != Signature.C_ARRAY) { //$NON-NLS-1$
throw new IllegalArgumentException();
}
- return scanTypeSignature(string, start + 1);
+
+ c = string[++start];
+ while(c == Signature.C_ARRAY) {
+ // need a minimum 2 char
+ if (start >= length - 1) {
+ throw new IllegalArgumentException();
+ }
+ c = string[++start];
+ }
+ return scanTypeSignature(string, start);
}
/**
@@ -2545,6 +2618,8 @@
return scanTypeVariableSignature(string, start);
case Signature.C_ARRAY :
return scanArrayTypeSignature(string, start);
+ case Signature.C_STAR:
+ return start;
default:
throw new IllegalArgumentException();
}
@@ -2677,7 +2752,7 @@
*/
public final static char[][] splitTypeLevelsSignature(String typeSignature) {
// In case of IJavaElement signature, replace '$' by '.'
- char[] source = Signature.removeCaptureFromMethod(typeSignature.toCharArray());
+ char[] source = Signature.removeCapture(typeSignature.toCharArray());
CharOperation.replace(source, '$', '.');
// Init counters and arrays
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
index ea0d966..b271672 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
@@ -164,6 +164,7 @@
classpath_disabledInclusionExclusionPatterns = Inclusion or exclusion patterns are disabled in project {1}, cannot selectively include or exclude from entry: ''{0}''
classpath_disabledMultipleOutputLocations = Multiple output locations are disabled in project {1}, cannot associate entry: ''{0}'' with a specific output
classpath_incompatibleLibraryJDKLevel = Incompatible .class files version in required binaries. Project ''{0}'' is targeting a {1} runtime, but is compiled against ''{2}'' which requires a {3} runtime
+classpath_duplicateEntryExtraAttribute = Duplicate extra attribute: ''{0}'' in classpath entry ''{1}'' for project {2}
### miscellaneous
file_notFound = File not found: ''{0}''
@@ -172,6 +173,7 @@
path_mustBeAbsolute = Path must be absolute
cache_invalidLoadFactor = Incorrect load factor
savedState_jobName = Processing Java changes since last activation
+javamodel_initialization = Initializing Java tooling
### access restrictions
restrictedAccess_project = The type {0} is not accessible due to restriction on required project {1}
@@ -314,19 +316,15 @@
classformat_ldc2_w_double = {0} <Double {2}> [{1}]
classformat_multianewarray = {0} {2}{3} [{1}]
classformat_new = {0} {2} [{1}]
-classformat_iinc = {0} {1} {2} [{3}]
-classformat_invokespecial = {0} {2}.{3}{4} [{1}]
-classformat_invokespecial_compact ={0} {2} [{1}]
-classformat_invokeinterface ={0} {3}.{4}{5} [{1}] [nargs: {2}]
-classformat_invokeinterface_compact ={0} {3} [{1}] [nargs: {2}]
-classformat_invokestatic ={0} {2}.{3}{4} [{1}]
-classformat_invokestatic_compact ={0} {2} [{1}]
-classformat_invokevirtual ={0} {2}.{3}{4} [{1}]
-classformat_invokevirtual_compact ={0} {2} [{1}]
-classformat_getfield ={0} {2}.{3} {4} [{1}]
-classformat_getstatic ={0} {2}.{3} {4} [{1}]
-classformat_putstatic ={0} {2}.{3} {4} [{1}]
-classformat_putfield ={0} {2}.{3} {4} [{1}]
+classformat_iinc = {0} {1} {2}{3}
+classformat_invokespecial ={0} {2} [{1}]
+classformat_invokeinterface ={0} {3} [{1}] [nargs: {2}]
+classformat_invokestatic ={0} {2} [{1}]
+classformat_invokevirtual ={0} {2} [{1}]
+classformat_getfield ={0} {2}.{3} : {4} [{1}]
+classformat_getstatic ={0} {2}.{3} : {4} [{1}]
+classformat_putstatic ={0} {2}.{3} : {4} [{1}]
+classformat_putfield ={0} {2}.{3} : {4} [{1}]
classformat_newarray_boolean = {0} boolean [{1}]
classformat_newarray_char = {0} char [{1}]
classformat_newarray_float = {0} float [{1}]
@@ -335,8 +333,8 @@
classformat_newarray_short = {0} short [{1}]
classformat_newarray_int = {0} int [{1}]
classformat_newarray_long = {0} long [{1}]
-classformat_store = {0} [{1}]
-classformat_load = {0} [{1}]
+classformat_store = {0}{1}
+classformat_load = {0}{1}
classfileformat_anyexceptionhandler=any
classfileformat_exceptiontableentry = [pc: {0}, pc: {1}] -> {2} when : {3}
classfileformat_linenumbertableentry = [pc: {0}, line: {1}]
diff --git a/org.eclipse.jdt.core/plugin.properties b/org.eclipse.jdt.core/plugin.properties
index f1c9b2e..c165a9d 100644
--- a/org.eclipse.jdt.core/plugin.properties
+++ b/org.eclipse.jdt.core/plugin.properties
@@ -21,5 +21,6 @@
javaTaskName=Java Task
javaPropertiesName=Java Properties File
javaSourceName=Java Source File
+javaClassName=Java Class File
jarManifestName=JAR Manifest File
extraJavaLikeFileExtensions=Extra Java-like File Extensions
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/plugin.xml b/org.eclipse.jdt.core/plugin.xml
index 89024aa..346f9ec 100644
--- a/org.eclipse.jdt.core/plugin.xml
+++ b/org.eclipse.jdt.core/plugin.xml
@@ -3,24 +3,12 @@
<!-- =================================================================================== -->
<!-- JDT/CORE Plug-in Manifest -->
<!-- =================================================================================== -->
-<plugin
- name = "%pluginName"
- id = "org.eclipse.jdt.core"
- version = "3.1.0"
- provider-name = "%providerName"
- class="org.eclipse.jdt.core.JavaCore">
+<plugin>
<!-- =================================================================================== -->
<!-- Prerequisite Plug-ins -->
<!-- =================================================================================== -->
-<requires>
- <import plugin="org.eclipse.core.resources"/>
- <import plugin="org.eclipse.core.runtime"/>
- <import plugin="org.eclipse.text"/>
- <import plugin="org.apache.ant" optional="true"/>
- <import plugin="org.eclipse.team.core" optional="true"/>
-</requires>
<!-- =================================================================================== -->
<!-- Runtime Libraries -->
@@ -187,6 +175,15 @@
base-type="org.eclipse.core.runtime.text"
priority="high"
file-extensions="java"/>
+ <!-- declares a content type for Java class files -->
+ <content-type id="javaClass" name="%javaClassName"
+ priority="high"
+ file-extensions="class">
+ <describer
+ class="org.eclipse.core.runtime.content.BinarySignatureDescriber">
+ <parameter name="signature" value="CA, FE, BA, BE"/>
+ </describer>
+ </content-type>
<!-- declares a content type for JAR manifest files -->
<content-type id="JARManifest" name="%jarManifestName"
base-type="org.eclipse.core.runtime.text"
@@ -202,5 +199,9 @@
point="org.eclipse.core.runtime.preferences">
<initializer class="org.eclipse.jdt.internal.core.JavaCorePreferenceInitializer"/>
</extension>
+<extension
+ point="org.eclipse.core.runtime.preferences">
+ <modifier class="org.eclipse.jdt.internal.core.JavaCorePreferenceModifyListener"/>
+</extension>
</plugin>
diff --git a/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd b/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
index 07085b2..c296a2f 100644
--- a/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
+++ b/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
@@ -58,6 +58,9 @@
the class that implements this container initializer.
This class must implement a public subclass of <code>org.eclipse.jdt.core.ClasspathContainerInitializer</code> with a public 0-argument constructor.
</documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.jdt.core.ClasspathContainerInitializer"/>
+ </appInfo>
</annotation>
</attribute>
</complexType>
diff --git a/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd b/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
index ca78aa8..c5d33a5 100644
--- a/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
+++ b/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
@@ -58,6 +58,9 @@
the class that implements this variable initializer.
This class must implement a public subclass of <code>org.eclipse.jdt.core.ClasspathVariableInitializer</code> with a public 0-argument constructor.
</documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.jdt.core.ClasspathVariableInitializer"/>
+ </appInfo>
</annotation>
</attribute>
</complexType>
diff --git a/org.eclipse.jdt.core/scripts/export-batch-jdtcom.xml b/org.eclipse.jdt.core/scripts/export-batch-jdtcom.xml
index 742ef03..19ad32d 100644
--- a/org.eclipse.jdt.core/scripts/export-batch-jdtcom.xml
+++ b/org.eclipse.jdt.core/scripts/export-batch-jdtcom.xml
@@ -22,13 +22,6 @@
</fileset>
<fileset dir="bin" includes="org/eclipse/jdt/internal/compiler/**,org/eclipse/jdt/core/compiler/**"/>
</zip>
-<!-- <jar
- jarfile="${dest}/jdtcom.jar"
- basedir="bin"
- includes="org/eclipse/jdt/internal/compiler/**,org/eclipse/jdt/core/compiler/**"
- manifest="META-INF/MANIFEST.MF"
- index="true"/> -->
-
<echo message="UPDATE jdtcomsrc.zip" />
<zip zipfile="${dest}/jdtcomsrc.zip">
<zipfileset dir="batch" />
diff --git a/org.eclipse.jdt.core/scripts/export-ejavac.xml b/org.eclipse.jdt.core/scripts/export-ejavac.xml
index 594271c..09ef024 100644
--- a/org.eclipse.jdt.core/scripts/export-ejavac.xml
+++ b/org.eclipse.jdt.core/scripts/export-ejavac.xml
@@ -2,11 +2,11 @@
<project name="export-executable" default="build" basedir="..">
<property name="version" value="310" />
- <property name="gcc-path" value="d:/gcj/thisiscool-gcc/gcc-4.0" />
+ <property name="gcc-path" value="D:\java_tools\thisiscool-gcc\gcc-4.0.old" />
<property name="binaryname" value="ejavac${version}" />
<property name="dest" value="../../bingcj/" />
<property name="work" value="${dest}tmp/" />
- <property name="source" value="d:/eclipse/workspaces/dev3.1/plugins/org.eclipse.jdt.core" />
+ <property name="source" value="D:/eclipse/workspaces/head/org.eclipse.jdt.core" />
<property name="gcj_script_name" value="export-executable.xml"/>
<target name="build">
diff --git a/org.eclipse.jdt.core/scripts/exportplugin.xml b/org.eclipse.jdt.core/scripts/exportplugin.xml
index 0433f0e..41ec08a 100644
--- a/org.eclipse.jdt.core/scripts/exportplugin.xml
+++ b/org.eclipse.jdt.core/scripts/exportplugin.xml
@@ -1,7 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- build script to create a plugin from ${plugin} -->
-<project name="${plugin}" default="export plug-in [_3.1.0]" basedir="..">
+<project name="${plugin}" default="export plug-in [_3.1.1]" basedir="..">
+
+<target name="export plug-in [_3.1.1]">
+ <antcall target="zz_internal_export">
+ <param name="jdt_core_version" value="3.1.1"/>
+ </antcall>
+</target>
<target name="export plug-in [_3.1.0]">
<antcall target="zz_internal_export">
@@ -82,8 +88,8 @@
</zip>
<delete file="${plugin-dir}/jdtCompilerAdapter.jar"/>
- <echo message="UPDATE jdtcoresrc.zip" />
- <zip zipfile="${plugin-dir}/jdtcoresrc.zip">
+ <echo message="UPDATE src.zip" />
+ <zip zipfile="${plugin-dir}/src.zip">
<fileset file="component.xml"/>
<fileset dir="batch" />
<fileset dir="codeassist" />
diff --git a/org.eclipse.jdt.core/scripts/ikvm_script.xml b/org.eclipse.jdt.core/scripts/ikvm_script.xml
new file mode 100644
index 0000000..7324c60
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/ikvm_script.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<project name="ecj" default="all" basedir="..">
+ <!-- target name="checkout">
+ <exec program="cvs" commandline="-z3 -d:pserver:anonymous@dev.eclipse.org:/home/eclipse co org.eclipse.jdt.core" />
+ </target>
+ <target name="allsources">
+ <exec program="cmd" commandline="/c dir /s/b org.eclipse.jdt.core\batch\*.java > allsources.lst" />
+ <exec program="cmd" commandline="/c dir /s/b org.eclipse.jdt.core\compiler\*.java >> allsources.lst" />
+ </target>
+ <target name="classes">
+ <exec program="../bin/ikvmstub.exe" commandline="IKVM.GNU.Classpath" useruntimeengine="true" />
+ <exec program="jikes" commandline="-nowarn -classpath IKVM.GNU.Classpath.jar;org.eclipse.jdt.core/compiler;org.eclipse.jdt.core/batch @allsources.lst" />
+ <delete file="IKVM.GNU.Classpath.jar" />
+ </target -->
+ <property name="ikvm_home" value="D:\java_tools\ikvm" />
+ <property name="dest" value="../../bingcj" />
+ <property name="work" value="${dest}/tmp" />
+ <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+ <property name="source" value="D:/eclipse/workspaces/head/org.eclipse.jdt.core" />
+
+ <target name="clean">
+ <echo message="target: ${dest}" />
+ <delete dir="${dest}" failonerror="no"/>
+ <mkdir dir="${dest}" />
+ </target>
+
+ <target name="retrieve_class_files">
+ <copy todir="${work}">
+ <fileset dir="${source}/batch/" includes='**/*.java' />
+ </copy>
+ <copy todir="${work}">
+ <fileset dir="${source}/compiler/" includes='**/*.java' />
+ </copy>
+
+ <echo message="copy resource files"/>
+ <copy todir="${dest}">
+ <fileset dir="${source}/compiler/" includes='**/*.rsc' />
+ </copy>
+
+ <echo message="copy properties files from compiler"/>
+ <copy todir="${dest}">
+ <fileset dir="${source}/compiler/" includes='**/*.properties' />
+ <fileset dir="${source}/batch/" includes='**/*.properties' />
+ </copy>
+
+ <javac srcdir="${work}" destdir="${dest}" nowarn="off" deprecation="off" source="1.4" debug="off" verbose="on">
+ <classpath>
+ <path location="${work}"/>
+ </classpath>
+ </javac>
+
+ <delete dir="${work}" failonerror="no"/>
+ </target>
+
+ <target name="ecj">
+ <exec dir="${dest}" executable="${ikvm_home}/bin/ikvmc.exe" output="${dest}/log.txt">
+ <arg line="-out:ecj.exe -main:org.eclipse.jdt.internal.compiler.batch.Main -recurse:./*.class -recurse:./*.properties -recurse:./*.rsc"/>
+ </exec>
+ <copy file="${ikvm_home}/bin/IKVM.Runtime.dll" todir="${dest}" />
+ <copy file="${ikvm_home}/bin/IKVM.GNU.Classpath.dll" todir="${dest}" />
+ </target>
+
+ <target name="all" depends="clean, retrieve_class_files, ecj">
+ </target>
+</project>
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java
index 2d8e8a5..22ed1ec 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java
@@ -19,12 +19,12 @@
import org.eclipse.jdt.internal.core.search.matching.*;
/**
- * A <code>SearchEngine</code> searches for Java elements following a search pattern.
+ * A {@link SearchEngine} searches for Java elements following a search pattern.
* The search can be limited to a search scope.
* <p>
* Various search patterns can be created using the factory methods
- * <code>createSearchPattern(String, int, int, boolean)</code>, <code>createSearchPattern(IJavaElement, int)</code>,
- * <code>createOrSearchPattern(ISearchPattern, ISearchPattern)</code>.
+ * {@link SearchPattern#createPattern(String, int, int, int)}, {@link SearchPattern#createPattern(IJavaElement, int)},
+ * {@link SearchPattern#createOrPattern(SearchPattern, SearchPattern)}.
* </p>
* <p>For example, one can search for references to a method in the hierarchy of a type,
* or one can search for the declarations of types starting with "Abstract" in a project.
@@ -324,26 +324,26 @@
* @param stringPattern the given pattern
* @param searchFor determines the nature of the searched elements
* <ul>
- * <li><code>IJavaSearchConstants.CLASS</code>: only look for classes</li>
- * <li><code>IJavaSearchConstants.INTERFACE</code>: only look for interfaces</li>
- * <li><code>IJavaSearchConstants.TYPE</code>: look for both classes and interfaces</li>
- * <li><code>IJavaSearchConstants.FIELD</code>: look for fields</li>
- * <li><code>IJavaSearchConstants.METHOD</code>: look for methods</li>
- * <li><code>IJavaSearchConstants.CONSTRUCTOR</code>: look for constructors</li>
- * <li><code>IJavaSearchConstants.PACKAGE</code>: look for packages</li>
+ * <li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
+ * <li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
+ * <li>{@link IJavaSearchConstants#TYPE}: look for both classes and interfaces</li>
+ * <li>{@link IJavaSearchConstants#FIELD}: look for fields</li>
+ * <li>{@link IJavaSearchConstants#METHOD}: look for methods</li>
+ * <li>{@link IJavaSearchConstants#CONSTRUCTOR}: look for constructors</li>
+ * <li>{@link IJavaSearchConstants#PACKAGE}: look for packages</li>
* </ul>
* @param limitTo determines the nature of the expected matches
* <ul>
- * <li><code>IJavaSearchConstants.DECLARATIONS</code>: will search declarations matching with the corresponding
+ * <li>{@link IJavaSearchConstants#DECLARATIONS}: will search declarations matching with the corresponding
* element. In case the element is a method, declarations of matching methods in subtypes will also
* be found, allowing to find declarations of abstract methods, etc.</li>
*
- * <li><code>IJavaSearchConstants.REFERENCES</code>: will search references to the given element.</li>
+ * <li>{@link IJavaSearchConstants#REFERENCES}: will search references to the given element.</li>
*
- * <li><code>IJavaSearchConstants.ALL_OCCURRENCES</code>: will search for either declarations or references as specified
+ * <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: will search for either declarations or references as specified
* above.</li>
*
- * <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: for interface, will find all types which implements a given interface.</li>
+ * <li>{@link IJavaSearchConstants#IMPLEMENTORS}: for interface, will find all types which implements a given interface.</li>
* </ul>
*
* @param isCaseSensitive indicates whether the search is case sensitive or not.
@@ -365,16 +365,16 @@
* @param element the Java element the search pattern is based on
* @param limitTo determines the nature of the expected matches
* <ul>
- * <li><code>IJavaSearchConstants.DECLARATIONS</code>: will search declarations matching with the corresponding
+ * <li>{@link IJavaSearchConstants#DECLARATIONS}: will search declarations matching with the corresponding
* element. In case the element is a method, declarations of matching methods in subtypes will also
* be found, allowing to find declarations of abstract methods, etc.</li>
*
- * <li><code>IJavaSearchConstants.REFERENCES</code>: will search references to the given element.</li>
+ * <li>{@link IJavaSearchConstants#REFERENCES}: will search references to the given element.</li>
*
- * <li><code>IJavaSearchConstants.ALL_OCCURRENCES</code>: will search for either declarations or references as specified
+ * <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: will search for either declarations or references as specified
* above.</li>
*
- * <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: for interface, will find all types which implements a given interface.</li>
+ * <li>{@link IJavaSearchConstants#IMPLEMENTORS}: for interface, will find all types which implements a given interface.</li>
* </ul>
* @return a search pattern for a Java element or <code>null</code> if the given element is ill-formed
* @deprecated Use {@link SearchPattern#createPattern(IJavaElement, int)} instead.
@@ -413,16 +413,16 @@
* @param workspace the workspace
* @param patternString the pattern to be searched for
* @param searchFor a hint what kind of Java element the string pattern represents.
- * Look into <code>IJavaSearchConstants</code> for valid values
+ * Look into {@link IJavaSearchConstants} for valid values
* @param limitTo one of the following values:
* <ul>
- * <li><code>IJavaSearchConstants.DECLARATIONS</code>: search
+ * <li>{@link IJavaSearchConstants#DECLARATIONS}: search
* for declarations only </li>
- * <li><code>IJavaSearchConstants.REFERENCES</code>: search
+ * <li>{@link IJavaSearchConstants#REFERENCES}: search
* for all references </li>
- * <li><code>IJavaSearchConstants.ALL_OCCURENCES</code>: search
+ * <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: search
* for both declarations and all references </li>
- * <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: search for
+ * <li>{@link IJavaSearchConstants#IMPLEMENTORS}: search for
* all implementors of an interface; the value is only valid if
* the Java element represents an interface</li>
* </ul>
@@ -459,13 +459,13 @@
* @param element the Java element to be searched for
* @param limitTo one of the following values:
* <ul>
- * <li><code>IJavaSearchConstants.DECLARATIONS</code>: search
+ * <li>{@link IJavaSearchConstants#DECLARATIONS}: search
* for declarations only </li>
- * <li><code>IJavaSearchConstants.REFERENCES</code>: search
+ * <li>{@link IJavaSearchConstants#REFERENCES}: search
* for all references </li>
- * <li><code>IJavaSearchConstants.ALL_OCCURENCES</code>: search
+ * <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: search
* for both declarations and all references </li>
- * <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: search for
+ * <li>{@link IJavaSearchConstants#IMPLEMENTORS}: search for
* all implementors of an interface; the value is only valid if
* the Java element represents an interface</li>
* </ul>
@@ -544,29 +544,33 @@
* for this type, or a wild-carded string for this type.
* @param matchRule one of
* <ul>
- * <li><code>SearchPattern.R_EXACT_MATCH</code> if the package name and type name are the full names
+ * <li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type name are the full names
* of the searched types.</li>
- * <li><code>SearchPattern.R_PREFIX_MATCH</code> if the package name and type name are prefixes of the names
+ * <li>{@link SearchPattern#R_PREFIX_MATCH} if the package name and type name are prefixes of the names
* of the searched types.</li>
- * <li><code>SearchPattern.R_PATTERN_MATCH</code> if the package name and type name contain wild-cards.</li>
+ * <li>{@link SearchPattern#R_PATTERN_MATCH} if the package name and type name contain wild-cards.</li>
* </ul>
- * combined with <code>SearchPattern.R_CASE_SENSITIVE</code>,
- * e.g. <code>R_EXACT_MATCH | R_CASE_SENSITIVE</code> if an exact and case sensitive match is requested,
- * or <code>R_PREFIX_MATCH</code> if a prefix non case sensitive match is requested.
- * @param searchFor one of
- * <ul>
- * <li><code>IJavaSearchConstants.CLASS</code> if searching for classes only</li>
- * <li><code>IJavaSearchConstants.INTERFACE</code> if searching for interfaces only</li>
- * <li><code>IJavaSearchConstants.TYPE</code> if searching for both classes and interfaces</li>
- * </ul>
+ * combined with {@link SearchPattern#R_CASE_SENSITIVE},
+ * e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
+ * or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
+ * @param searchFor determines the nature of the searched elements
+ * <ul>
+ * <li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
+ * <li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
+ * <li>{@link IJavaSearchConstants#ENUM}: only look for enumeration</li>
+ * <li>{@link IJavaSearchConstants#ANNOTATION_TYPE}: only look for annotation type</li>
+ * <li>{@link IJavaSearchConstants#CLASS_AND_ENUM}: only look for classes and enumerations</li>
+ * <li>{@link IJavaSearchConstants#CLASS_AND_INTERFACE}: only look for classes and interfaces</li>
+ * <li>{@link IJavaSearchConstants#TYPE}: look for all types (ie. classes, interfaces, enum and annotation types)</li>
+ * </ul>
* @param scope the scope to search in
* @param nameRequestor the requestor that collects the results of the search
* @param waitingPolicy one of
* <ul>
- * <li><code>IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH</code> if the search should start immediately</li>
- * <li><code>IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH</code> if the search should be cancelled if the
+ * <li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+ * <li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
* underlying indexer has not finished indexing the workspace</li>
- * <li><code>IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH</code> if the search should wait for the
+ * <li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
* underlying indexer to finish indexing the workspace</li>
* </ul>
* @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
@@ -575,7 +579,7 @@
* <ul>
* <li>the classpath is incorrectly set</li>
* </ul>
- * @since 3.0
+ * @since 3.1
*/
public void searchAllTypeNames(
final char[] packageName,
@@ -601,10 +605,10 @@
* @param nameRequestor the requestor that collects the results of the search
* @param waitingPolicy one of
* <ul>
- * <li><code>IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH</code> if the search should start immediately</li>
- * <li><code>IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH</code> if the search should be cancelled if the
+ * <li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+ * <li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
* underlying indexer has not finished indexing the workspace</li>
- * <li><code>IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH</code> if the search should wait for the
+ * <li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
* underlying indexer to finish indexing the workspace</li>
* </ul>
* @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
@@ -647,29 +651,29 @@
* for this type, or a wild-carded string for this type.
* @param matchRule one of
* <ul>
- * <li><code>SearchPattern.R_EXACT_MATCH</code> if the package name and type name are the full names
+ * <li>{@link SearchPattern#R_EXACT_MATCH} if the package name and type name are the full names
* of the searched types.</li>
- * <li><code>SearchPattern.R_PREFIX_MATCH</code> if the package name and type name are prefixes of the names
+ * <li>{@link SearchPattern#R_PREFIX_MATCH} if the package name and type name are prefixes of the names
* of the searched types.</li>
- * <li><code>SearchPattern.R_PATTERN_MATCH</code> if the package name and type name contain wild-cards.</li>
+ * <li>{@link SearchPattern#R_PATTERN_MATCH} if the package name and type name contain wild-cards.</li>
* </ul>
- * combined with <code>SearchPattern.R_CASE_SENSITIVE</code>,
- * e.g. <code>R_EXACT_MATCH | R_CASE_SENSITIVE</code> if an exact and case sensitive match is requested,
- * or <code>R_PREFIX_MATCH</code> if a prefix non case sensitive match is requested.
+ * combined with {@link SearchPattern#R_CASE_SENSITIVE},
+ * e.g. {@link SearchPattern#R_EXACT_MATCH} | {@link SearchPattern#R_CASE_SENSITIVE} if an exact and case sensitive match is requested,
+ * or {@link SearchPattern#R_PREFIX_MATCH} if a prefix non case sensitive match is requested.
* @param searchFor one of
* <ul>
- * <li><code>IJavaSearchConstants.CLASS</code> if searching for classes only</li>
- * <li><code>IJavaSearchConstants.INTERFACE</code> if searching for interfaces only</li>
- * <li><code>IJavaSearchConstants.TYPE</code> if searching for both classes and interfaces</li>
+ * <li>{@link IJavaSearchConstants#CLASS} if searching for classes only</li>
+ * <li>{@link IJavaSearchConstants#INTERFACE} if searching for interfaces only</li>
+ * <li>{@link IJavaSearchConstants#TYPE} if searching for both classes and interfaces</li>
* </ul>
* @param scope the scope to search in
* @param nameRequestor the requestor that collects the results of the search
* @param waitingPolicy one of
* <ul>
- * <li><code>IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH</code> if the search should start immediately</li>
- * <li><code>IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH</code> if the search should be cancelled if the
+ * <li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+ * <li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
* underlying indexer has not finished indexing the workspace</li>
- * <li><code>IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH</code> if the search should wait for the
+ * <li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
* underlying indexer to finish indexing the workspace</li>
* </ul>
* @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
@@ -707,27 +711,27 @@
* for this type, or a wild-carded string for this type.
* @param matchMode one of
* <ul>
- * <li><code>IJavaSearchConstants.EXACT_MATCH</code> if the package name and type name are the full names
+ * <li>{@link IJavaSearchConstants#EXACT_MATCH} if the package name and type name are the full names
* of the searched types.</li>
- * <li><code>IJavaSearchConstants.PREFIX_MATCH</code> if the package name and type name are prefixes of the names
+ * <li>{@link IJavaSearchConstants#PREFIX_MATCH} if the package name and type name are prefixes of the names
* of the searched types.</li>
- * <li><code>IJavaSearchConstants.PATTERN_MATCH</code> if the package name and type name contain wild-cards.</li>
+ * <li>{@link IJavaSearchConstants#PATTERN_MATCH} if the package name and type name contain wild-cards.</li>
* </ul>
* @param isCaseSensitive whether the search should be case sensitive
* @param searchFor one of
* <ul>
- * <li><code>IJavaSearchConstants.CLASS</code> if searching for classes only</li>
- * <li><code>IJavaSearchConstants.INTERFACE</code> if searching for interfaces only</li>
- * <li><code>IJavaSearchConstants.TYPE</code> if searching for both classes and interfaces</li>
+ * <li>{@link IJavaSearchConstants#CLASS} if searching for classes only</li>
+ * <li>{@link IJavaSearchConstants#INTERFACE} if searching for interfaces only</li>
+ * <li>{@link IJavaSearchConstants#TYPE} if searching for both classes and interfaces</li>
* </ul>
* @param scope the scope to search in
* @param nameRequestor the requestor that collects the results of the search
* @param waitingPolicy one of
* <ul>
- * <li><code>IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH</code> if the search should start immediately</li>
- * <li><code>IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH</code> if the search should be cancelled if the
+ * <li>{@link IJavaSearchConstants#FORCE_IMMEDIATE_SEARCH} if the search should start immediately</li>
+ * <li>{@link IJavaSearchConstants#CANCEL_IF_NOT_READY_TO_SEARCH} if the search should be cancelled if the
* underlying indexer has not finished indexing the workspace</li>
- * <li><code>IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH</code> if the search should wait for the
+ * <li>{@link IJavaSearchConstants#WAIT_UNTIL_READY_TO_SEARCH} if the search should wait for the
* underlying indexer to finish indexing the workspace</li>
* </ul>
* @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java
index c4129c9..17efa21 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java
@@ -63,6 +63,7 @@
// store other necessary information
private boolean raw = false;
+ private boolean implicit = false;
/**
* Creates a new search match.
@@ -201,6 +202,20 @@
}
/**
+ * Returns whether the associated element is implicit or not.
+ *
+ * Note that this piece of information is currently only implemented
+ * for implicit member pair value in annotation.
+ *
+ * @return <code>true</code> if this match is associated to an implicit
+ * element and <code>false</code> otherwise
+ * @since 3.1
+ */
+ public final boolean isImplicit() {
+ return this.implicit;
+ }
+
+ /**
* Returns whether the associated element is a raw type/method or not.
*
* @return <code>true</code> if this match is associated to a raw
@@ -254,6 +269,19 @@
}
/**
+ * Sets whether the associated element is implicit or not.
+ * Typically, this is the case when match is on an implicit constructor
+ * or an implicit member pair value in annotation.
+ *
+ * @param implicit <code>true</code> if this match is associated to an implicit
+ * element and <code>false</code> otherwise
+ * @since 3.1
+ */
+ public final void setImplicit(boolean implicit) {
+ this.implicit = implicit;
+ }
+
+ /**
* Sets the length of this search match.
*
* @param length the length of the match, or -1 if unknown
@@ -290,7 +318,7 @@
}
/**
- * Returns the rule used while creating the match.
+ * Set the rule used while reporting the match.
*
* @param rule one of {@link SearchPattern#R_FULL_MATCH}, {@link SearchPattern#R_EQUIVALENT_MATCH}
* or {@link SearchPattern#R_ERASURE_MATCH}
@@ -301,7 +329,7 @@
}
/**
- * Returns whether the associated element is a raw type/method or not.
+ * Set whether the associated element is a raw type/method or not.
*
* @param raw <code>true</code> if this search match is associated to a raw
* type or method and <code>false</code> otherwise
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java
index ee39ea4..a61f4fa 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java
@@ -14,6 +14,7 @@
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.internal.core.JavaModel;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
@@ -173,8 +174,13 @@
public final void scheduleDocumentIndexing(SearchDocument document, IPath indexLocation) {
IPath documentPath = new Path(document.getPath());
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- IResource resource = root.findMember(documentPath);
- IPath containerPath = resource == null ? documentPath : resource.getProject().getFullPath();
+ Object file = JavaModel.getTarget(root, documentPath, true);
+ IPath containerPath = documentPath;
+ if (file instanceof IResource) {
+ containerPath = ((IResource)file).getProject().getFullPath();
+ } else if (file == null) {
+ containerPath = documentPath.removeLastSegments(documentPath.segmentCount()-1);
+ }
IndexManager manager = JavaModelManager.getJavaModelManager().getIndexManager();
String osIndexLocation = indexLocation.toOSString();
// TODO (jerome) should not have to create index manually, should expose API that recreates index instead
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
index 84f57f6..ac39929 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
@@ -339,7 +339,7 @@
* <li><Exception>Sample(Exception)</li>
* </ul>
* Type arguments have the same pattern that for type patterns
- * @see #createTypePattern(String,int,int)
+ * @see #createTypePattern(String,int,int,char)
*/
private static SearchPattern createMethodOrConstructorPattern(String patternString, int limitTo, int matchRule, boolean isConstructor) {
@@ -767,7 +767,11 @@
* <ul>
* <li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
* <li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
- * <li>{@link IJavaSearchConstants#TYPE}: look for both classes and interfaces</li>
+ * <li>{@link IJavaSearchConstants#ENUM}: only look for enumeration</li>
+ * <li>{@link IJavaSearchConstants#ANNOTATION_TYPE}: only look for annotation type</li>
+ * <li>{@link IJavaSearchConstants#CLASS_AND_ENUM}: only look for classes and enumerations</li>
+ * <li>{@link IJavaSearchConstants#CLASS_AND_INTERFACE}: only look for classes and interfaces</li>
+ * <li>{@link IJavaSearchConstants#TYPE}: look for all types (ie. classes, interfaces, enum and annotation types)</li>
* <li>{@link IJavaSearchConstants#FIELD}: look for fields</li>
* <li>{@link IJavaSearchConstants#METHOD}: look for methods</li>
* <li>{@link IJavaSearchConstants#CONSTRUCTOR}: look for constructors</li>
@@ -808,8 +812,20 @@
limitTo &= ~(IJavaSearchConstants.IGNORE_DECLARING_TYPE+IJavaSearchConstants.IGNORE_RETURN_TYPE);
switch (searchFor) {
+ case IJavaSearchConstants.CLASS:
+ return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.CLASS_SUFFIX);
+ case IJavaSearchConstants.CLASS_AND_INTERFACE:
+ return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.CLASS_AND_INTERFACE_SUFFIX);
+ case IJavaSearchConstants.CLASS_AND_ENUM:
+ return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.CLASS_AND_ENUM_SUFFIX);
+ case IJavaSearchConstants.INTERFACE:
+ return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.INTERFACE_SUFFIX);
+ case IJavaSearchConstants.ENUM:
+ return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.ENUM_SUFFIX);
+ case IJavaSearchConstants.ANNOTATION_TYPE:
+ return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.ANNOTATION_TYPE_SUFFIX);
case IJavaSearchConstants.TYPE:
- return createTypePattern(stringPattern, limitTo, matchRule);
+ return createTypePattern(stringPattern, limitTo, matchRule, IIndexConstants.TYPE_SUFFIX);
case IJavaSearchConstants.METHOD:
return createMethodOrConstructorPattern(stringPattern, limitTo, matchRule, false/*not a constructor*/);
case IJavaSearchConstants.CONSTRUCTOR:
@@ -1265,16 +1281,16 @@
* Type pattern are formed by [qualification '.']type [typeArguments].
* e.g. java.lang.Object
* Runnable
- * List<String>
+ * List<String>
*
* @since 3.1
* Type arguments can be specified to search references to parameterized types.
- * and look as follow: '<' { [ '?' {'extends'|'super'} ] type ( ',' [ '?' {'extends'|'super'} ] type )* | '?' } '>'
+ * and look as follow: '<' { [ '?' {'extends'|'super'} ] type ( ',' [ '?' {'extends'|'super'} ] type )* | '?' } '>'
* Please note that:
- * - '*' is not valid inside type arguments definition <>
- * - '?' is treated as a wildcard when it is inside <> (ie. it must be put on first position of the type argument)
+ * - '*' is not valid inside type arguments definition <>
+ * - '?' is treated as a wildcard when it is inside <> (ie. it must be put on first position of the type argument)
*/
- private static SearchPattern createTypePattern(String patternString, int limitTo, int matchRule) {
+ private static SearchPattern createTypePattern(String patternString, int limitTo, int matchRule, char indexSuffix) {
Scanner scanner = new Scanner(false /*comment*/, true /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3/*sourceLevel*/, null /*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
scanner.setSource(patternString.toCharArray());
@@ -1356,14 +1372,14 @@
}
switch (limitTo) {
case IJavaSearchConstants.DECLARATIONS : // cannot search for explicit member types
- return new QualifiedTypeDeclarationPattern(qualificationChars, typeChars, IIndexConstants.TYPE_SUFFIX, matchRule);
+ return new QualifiedTypeDeclarationPattern(qualificationChars, typeChars, indexSuffix, matchRule);
case IJavaSearchConstants.REFERENCES :
return new TypeReferencePattern(qualificationChars, typeChars, typeSignature, matchRule);
case IJavaSearchConstants.IMPLEMENTORS :
return new SuperTypeReferencePattern(qualificationChars, typeChars, true, matchRule);
case IJavaSearchConstants.ALL_OCCURRENCES :
return new OrPattern(
- new QualifiedTypeDeclarationPattern(qualificationChars, typeChars, IIndexConstants.TYPE_SUFFIX, matchRule),// cannot search for explicit member types
+ new QualifiedTypeDeclarationPattern(qualificationChars, typeChars, indexSuffix, matchRule),// cannot search for explicit member types
new TypeReferencePattern(qualificationChars, typeChars, matchRule));
}
return null;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
index 23cbcd7..51ab864 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
@@ -35,7 +35,7 @@
private HashtableOfObject categoryTables; // category name -> HashtableOfObject(words -> int[] of document #'s) or offset if not read yet
private char[] cachedCategoryName;
-public static final String SIGNATURE= "INDEX VERSION 1.100"; //$NON-NLS-1$
+public static final String SIGNATURE= "INDEX VERSION 1.106"; //$NON-NLS-1$
public static boolean DEBUG = false;
private static final int RE_INDEXED = -1;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
index 118f2c5..816ecb1 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
@@ -79,8 +79,13 @@
this.memoryIndex.addIndexEntry(category, key, containerRelativePath);
}
public String containerRelativePath(String documentPath) {
- int jarSeparator = documentPath.indexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR);
- return documentPath.substring((jarSeparator == -1 ? this.containerPath.length() : jarSeparator) + 1);
+ int index = documentPath.indexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR);
+ if (index == -1) {
+ index = this.containerPath.length();
+ if (documentPath.length() <= index)
+ throw new IllegalArgumentException("Document path " + documentPath + " must be relative to " + this.containerPath); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return documentPath.substring(index + 1);
}
public File getIndexFile() {
if (this.diskIndex == null) return null;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
index 9d39284..f800536 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
@@ -131,19 +131,19 @@
public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, int includeMask) {
JavaSearchScope scope = new JavaSearchScope();
HashSet visitedProjects = new HashSet(2);
- try {
- for (int i = 0, length = elements.length; i < length; i++) {
- IJavaElement element = elements[i];
- if (element != null) {
+ for (int i = 0, length = elements.length; i < length; i++) {
+ IJavaElement element = elements[i];
+ if (element != null) {
+ try {
if (element instanceof JavaProject) {
scope.add((JavaProject)element, includeMask, visitedProjects);
} else {
scope.add(element);
}
+ } catch (JavaModelException e) {
+ // ignore
}
}
- } catch (JavaModelException e) {
- // ignore
}
return scope;
}
@@ -154,7 +154,7 @@
* @return a new workspace scope
*/
public static IJavaSearchScope createWorkspaceScope() {
- return JavaWorkspaceScope.createScope();
+ return JavaModelManager.getJavaModelManager().getWorkspaceScope();
}
/**
@@ -186,7 +186,7 @@
SubProgressMonitor subMonitor= monitor==null ? null : new SubProgressMonitor(monitor, 1000);
if (subMonitor != null) subMonitor.beginTask("", 1000); //$NON-NLS-1$
try {
- if (subMonitor != null) subMonitor.subTask(Messages.bind(Messages.engine_searching_indexing, (new String[] {participant.getDescription()})));
+ if (subMonitor != null) subMonitor.subTask(Messages.bind(Messages.engine_searching_indexing, new String[] {participant.getDescription()}));
participant.beginSearching();
requestor.enterParticipant(participant);
PathCollector pathCollector = new PathCollector();
@@ -197,7 +197,7 @@
if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
// locate index matches if any (note that all search matches could have been issued during index querying)
- if (subMonitor != null) subMonitor.subTask(Messages.bind(Messages.engine_searching_matching, (new String[] {participant.getDescription()})));
+ if (subMonitor != null) subMonitor.subTask(Messages.bind(Messages.engine_searching_matching, new String[] {participant.getDescription()}));
String[] indexMatchPaths = pathCollector.getPaths();
pathCollector = null; // release
int indexMatchLength = indexMatchPaths == null ? 0 : indexMatchPaths.length;
@@ -338,11 +338,35 @@
return getWorkingCopies();
}
+ boolean match(char patternTypeSuffix, int modifiers) {
+ switch(patternTypeSuffix) {
+ case IIndexConstants.CLASS_SUFFIX :
+ return (modifiers & (Flags.AccAnnotation | Flags.AccInterface | Flags.AccEnum)) == 0;
+ case IIndexConstants.CLASS_AND_INTERFACE_SUFFIX:
+ return (modifiers & (Flags.AccAnnotation | Flags.AccEnum)) == 0;
+ case IIndexConstants.CLASS_AND_ENUM_SUFFIX:
+ return (modifiers & (Flags.AccAnnotation | Flags.AccInterface)) == 0;
+ case IIndexConstants.INTERFACE_SUFFIX :
+ return (modifiers & Flags.AccInterface) != 0;
+ case IIndexConstants.ENUM_SUFFIX :
+ return (modifiers & Flags.AccEnum) != 0;
+ case IIndexConstants.ANNOTATION_TYPE_SUFFIX :
+ return (modifiers & Flags.AccAnnotation) != 0;
+ }
+ return true;
+ }
+
boolean match(char patternTypeSuffix, char[] patternPkg, char[] patternTypeName, int matchRule, int typeKind, char[] pkg, char[] typeName) {
switch(patternTypeSuffix) {
case IIndexConstants.CLASS_SUFFIX :
if (typeKind != IGenericType.CLASS_DECL) return false;
break;
+ case IIndexConstants.CLASS_AND_INTERFACE_SUFFIX:
+ if (typeKind != IGenericType.CLASS_DECL && typeKind != IGenericType.INTERFACE_DECL) return false;
+ break;
+ case IIndexConstants.CLASS_AND_ENUM_SUFFIX:
+ if (typeKind != IGenericType.CLASS_DECL && typeKind != IGenericType.ENUM_DECL) return false;
+ break;
case IIndexConstants.INTERFACE_SUFFIX :
if (typeKind != IGenericType.INTERFACE_DECL) return false;
break;
@@ -361,6 +385,9 @@
if (patternTypeName != null) {
int matchMode = matchRule - (isCaseSensitive ? SearchPattern.R_CASE_SENSITIVE : 0);
+ if (!isCaseSensitive) {
+ patternTypeName = CharOperation.toLowerCase(patternTypeName);
+ }
switch(matchMode) {
case SearchPattern.R_EXACT_MATCH :
return CharOperation.equals(patternTypeName, typeName, isCaseSensitive);
@@ -391,6 +418,9 @@
*@since 3.0
*/
public void search(SearchPattern pattern, SearchParticipant[] participants, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException {
+ if (VERBOSE) {
+ System.out.println("BasicSearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)"); //$NON-NLS-1$
+ }
findMatches(pattern, participants, scope, requestor, monitor);
}
@@ -415,12 +445,16 @@
* combined with <code>SearchPattern.R_CASE_SENSITIVE</code>,
* e.g. <code>R_EXACT_MATCH | R_CASE_SENSITIVE</code> if an exact and case sensitive match is requested,
* or <code>R_PREFIX_MATCH</code> if a prefix non case sensitive match is requested.
- * @param searchFor one of
- * <ul>
- * <li><code>IJavaSearchConstants.CLASS</code> if searching for classes only</li>
- * <li><code>IJavaSearchConstants.INTERFACE</code> if searching for interfaces only</li>
- * <li><code>IJavaSearchConstants.TYPE</code> if searching for both classes and interfaces</li>
- * </ul>
+ * @param searchFor determines the nature of the searched elements
+ * <ul>
+ * <li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
+ * <li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
+ * <li>{@link IJavaSearchConstants#ENUM}: only look for enumeration</li>
+ * <li>{@link IJavaSearchConstants#ANNOTATION_TYPE}: only look for annotation type</li>
+ * <li>{@link IJavaSearchConstants#CLASS_AND_ENUM}: only look for classes and enumerations</li>
+ * <li>{@link IJavaSearchConstants#CLASS_AND_INTERFACE}: only look for classes and interfaces</li>
+ * <li>{@link IJavaSearchConstants#TYPE}: look for all types (ie. classes, interfaces, enum and annotation types)</li>
+ * </ul>
* @param scope the scope to search in
* @param nameRequestor the requestor that collects the results of the search
* @param waitingPolicy one of
@@ -449,6 +483,15 @@
int waitingPolicy,
IProgressMonitor progressMonitor) throws JavaModelException {
+ if (VERBOSE) {
+ System.out.println("BasicSearchEngine.searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
+ System.out.println(" - package name: "+(packageName==null?"null":new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
+ System.out.println(" - type name: "+(typeName==null?"null":new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
+ System.out.println(" - match rule: "+matchRule); //$NON-NLS-1$
+ System.out.println(" - search for: "+searchFor); //$NON-NLS-1$
+ System.out.println(" - scope: "+scope); //$NON-NLS-1$
+ }
+
IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
final char typeSuffix;
@@ -456,6 +499,12 @@
case IJavaSearchConstants.CLASS :
typeSuffix = IIndexConstants.CLASS_SUFFIX;
break;
+ case IJavaSearchConstants.CLASS_AND_INTERFACE :
+ typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX;
+ break;
+ case IJavaSearchConstants.CLASS_AND_ENUM :
+ typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX;
+ break;
case IJavaSearchConstants.INTERFACE :
typeSuffix = IIndexConstants.INTERFACE_SUFFIX;
break;
@@ -493,16 +542,10 @@
&& !workingCopyPaths.contains(documentPath)) { // filter out working copies
if (access != null) {
// Compute document relative path
- int pos = documentPath.lastIndexOf('.');
- char[] extension = null;
- if (pos >= 0 && pos > documentPath.lastIndexOf('/')) {
- extension = documentPath.substring(pos).toCharArray();
- }
- int pkgLength = record.pkg==null ? 0 : record.pkg.length+1;
+ int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1;
int nameLength = record.simpleName==null ? 0 : record.simpleName.length;
- int extLength = extension==null ? 0 : extension.length;
- char[] path = new char[pkgLength+nameLength+extLength];
- pos = 0;
+ char[] path = new char[pkgLength+nameLength];
+ int pos = 0;
if (pkgLength > 0) {
System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
CharOperation.replace(path, '.', '/');
@@ -512,16 +555,15 @@
if (nameLength > 0) {
System.arraycopy(record.simpleName, 0, path, pos, nameLength);
pos += nameLength;
- if (extLength > 0) {
- System.arraycopy(extension, 0, path, pos, extLength);
- }
}
// Update access restriction if path is not empty
if (pos > 0) {
accessRestriction = access.getViolatedRestriction(path);
}
}
- nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
+ if (match(record.typeSuffix, record.modifiers)) {
+ nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
+ }
}
return true;
}
@@ -671,6 +713,14 @@
int waitingPolicy,
IProgressMonitor progressMonitor) throws JavaModelException {
+ if (VERBOSE) {
+ System.out.println("BasicSearchEngine.searchAllTypeNames(char[][], char[][], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
+ System.out.println(" - package name: "+(qualifications==null?"null":new String(CharOperation.concatWith(qualifications, ',')))); //$NON-NLS-1$ //$NON-NLS-2$
+ System.out.println(" - type name: "+(typeNames==null?"null":new String(CharOperation.concatWith(typeNames, ',')))); //$NON-NLS-1$ //$NON-NLS-2$
+ System.out.println(" - match rule: "+matchRule); //$NON-NLS-1$
+ System.out.println(" - search for: "+searchFor); //$NON-NLS-1$
+ System.out.println(" - scope: "+scope); //$NON-NLS-1$
+ }
IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
final char typeSuffix;
@@ -678,6 +728,12 @@
case IJavaSearchConstants.CLASS :
typeSuffix = IIndexConstants.CLASS_SUFFIX;
break;
+ case IJavaSearchConstants.CLASS_AND_INTERFACE :
+ typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX;
+ break;
+ case IJavaSearchConstants.CLASS_AND_ENUM :
+ typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX;
+ break;
case IJavaSearchConstants.INTERFACE :
typeSuffix = IIndexConstants.INTERFACE_SUFFIX;
break;
@@ -709,15 +765,10 @@
AccessRestriction accessRestriction = null;
if (access != null) {
// Compute document relative path
- int pos = documentPath.lastIndexOf('.');
- char[] extension = null;
- if (pos >= 0 && pos > documentPath.lastIndexOf('/'))
- extension = documentPath.substring(pos).toCharArray();
- int qualificationLength = record.qualification == null ? 0 : record.qualification.length + 1;
+ int qualificationLength = (record.qualification == null || record.qualification.length == 0) ? 0 : record.qualification.length + 1;
int nameLength = record.simpleName == null ? 0 : record.simpleName.length;
- int extLength = extension == null ? 0 : extension.length;
- char[] path = new char[qualificationLength + nameLength + extLength];
- pos = 0;
+ char[] path = new char[qualificationLength + nameLength];
+ int pos = 0;
if (qualificationLength > 0) {
System.arraycopy(record.qualification, 0, path, pos, qualificationLength - 1);
CharOperation.replace(path, '.', '/');
@@ -727,8 +778,6 @@
if (nameLength > 0) {
System.arraycopy(record.simpleName, 0, path, pos, nameLength);
pos += nameLength;
- if (extLength > 0)
- System.arraycopy(extension, 0, path, pos, extLength);
}
// Update access restriction if path is not empty
if (pos > 0) {
@@ -861,13 +910,16 @@
}
public void searchDeclarations(IJavaElement enclosingElement, SearchRequestor requestor, SearchPattern pattern, IProgressMonitor monitor) throws JavaModelException {
+ if (VERBOSE) {
+ System.out.println(" - java element: "+enclosingElement); //$NON-NLS-1$
+ }
IJavaSearchScope scope = createJavaSearchScope(new IJavaElement[] {enclosingElement});
IResource resource = this.getResource(enclosingElement);
try {
if (resource instanceof IFile) {
try {
requestor.beginReporting();
- if (BasicSearchEngine.VERBOSE) {
+ if (VERBOSE) {
System.out.println("Searching for " + pattern + " in " + resource.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
}
SearchParticipant participant = getDefaultSearchParticipant();
@@ -938,6 +990,9 @@
* @since 3.0
*/
public void searchDeclarationsOfAccessedFields(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+ if (VERBOSE) {
+ System.out.println("BasicSearchEngine.searchDeclarationsOfAccessedFields(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$
+ }
SearchPattern pattern = new DeclarationOfAccessedFieldsPattern(enclosingElement);
searchDeclarations(enclosingElement, requestor, pattern, monitor);
}
@@ -980,6 +1035,9 @@
* @since 3.0
*/
public void searchDeclarationsOfReferencedTypes(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+ if (VERBOSE) {
+ System.out.println("BasicSearchEngine.searchDeclarationsOfReferencedTypes(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$
+ }
SearchPattern pattern = new DeclarationOfReferencedTypesPattern(enclosingElement);
searchDeclarations(enclosingElement, requestor, pattern, monitor);
}
@@ -1025,6 +1083,9 @@
* @since 3.0
*/
public void searchDeclarationsOfSentMessages(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
+ if (VERBOSE) {
+ System.out.println("BasicSearchEngine.searchDeclarationsOfSentMessages(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$
+ }
SearchPattern pattern = new DeclarationOfReferencedMethodsPattern(enclosingElement);
searchDeclarations(enclosingElement, requestor, pattern, monitor);
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java
index b9f378e..07fa0fd 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java
@@ -110,13 +110,8 @@
JavaModelManager.PerProjectInfo perProjectInfo = javaProject.getPerProjectInfo();
for (int i = 0, length = entries.length; i < length; i++) {
IClasspathEntry entry = entries[i];
- IClasspathEntry rawEntry = null;
- if (perProjectInfo != null && perProjectInfo.resolvedPathToRawEntries != null) {
- rawEntry = (IClasspathEntry) perProjectInfo.resolvedPathToRawEntries.get(entry.getPath());
- }
- if (rawEntry == null) continue;
AccessRuleSet access = null;
- ClasspathEntry cpEntry = (ClasspathEntry) rawEntry;
+ ClasspathEntry cpEntry = (ClasspathEntry) entry;
if (referringEntry != null) {
// Add only exported entries.
// Source folder are implicitly exported.
@@ -127,13 +122,19 @@
access = cpEntry.getAccessRuleSet();
switch (entry.getEntryKind()) {
case IClasspathEntry.CPE_LIBRARY:
+ IClasspathEntry rawEntry = null;
+ if (perProjectInfo != null && perProjectInfo.resolvedPathToRawEntries != null) {
+ rawEntry = (IClasspathEntry) perProjectInfo.resolvedPathToRawEntries.get(entry.getPath());
+ }
+ if (rawEntry == null) break;
switch (rawEntry.getEntryKind()) {
case IClasspathEntry.CPE_LIBRARY:
case IClasspathEntry.CPE_VARIABLE:
if ((includeMask & APPLICATION_LIBRARIES) != 0) {
IPath path = entry.getPath();
if (pathToAdd == null || pathToAdd.equals(path)) {
- add("", path.toString(), true, access); //$NON-NLS-1$
+ String pathToString = path.getDevice() == null ? path.toString() : path.toOSString();
+ add("", pathToString, true, access); //$NON-NLS-1$
addEnclosingProjectOrJar(path);
}
}
@@ -145,7 +146,8 @@
|| (includeMask & SYSTEM_LIBRARIES) != 0) {
IPath path = entry.getPath();
if (pathToAdd == null || pathToAdd.equals(path)) {
- add("", path.toString(), true, access); //$NON-NLS-1$
+ String pathToString = path.getDevice() == null ? path.toString() : path.toOSString();
+ add("", pathToString, true, access); //$NON-NLS-1$
addEnclosingProjectOrJar(path);
}
}
@@ -178,6 +180,7 @@
*/
public void add(IJavaElement element) throws JavaModelException {
IPath containerPath = null;
+ String containerPathToString = null;
int includeMask = SOURCES | APPLICATION_LIBRARIES | SYSTEM_LIBRARIES;
switch (element.getElementType()) {
case IJavaElement.JAVA_MODEL:
@@ -190,20 +193,29 @@
IPackageFragmentRoot root = (IPackageFragmentRoot)element;
IPath rootPath = root.getPath();
containerPath = root.getKind() == IPackageFragmentRoot.K_SOURCE ? root.getParent().getPath() : rootPath;
- add("", containerPath.toString(), true, null); //$NON-NLS-1$
+ containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
+ IResource rootResource = root.getResource();
+ if (rootResource != null && rootResource.isAccessible()) {
+ String relativePath = Util.relativePath(rootResource.getFullPath(), containerPath.segmentCount());
+ add(relativePath, containerPathToString, true, null);
+ } else {
+ add("", containerPathToString, true, null); //$NON-NLS-1$
+ }
break;
case IJavaElement.PACKAGE_FRAGMENT:
root = (IPackageFragmentRoot)element.getParent();
if (root.isArchive()) {
String relativePath = Util.concatWith(((PackageFragment) element).names, '/');
containerPath = root.getPath();
- add(relativePath, containerPath.toString(), false, null);
+ containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
+ add(relativePath, containerPathToString, false, null);
} else {
IResource resource = element.getResource();
if (resource != null && resource.isAccessible()) {
containerPath = root.getKind() == IPackageFragmentRoot.K_SOURCE ? root.getParent().getPath() : root.getPath();
+ containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
String relativePath = Util.relativePath(resource.getFullPath(), containerPath.segmentCount());
- add(relativePath, containerPath.toString(), false, null);
+ add(relativePath, containerPathToString, false, null);
}
}
break;
@@ -224,7 +236,8 @@
containerPath = root.getPath();
relativePath = getPath(element, true/*relative path*/).toString();
}
- add(relativePath, containerPath.toString(), true, null);
+ containerPathToString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
+ add(relativePath, containerPathToString, true, null);
}
if (containerPath != null)
@@ -301,9 +314,22 @@
private boolean encloses(String scopePath, String path, int index) {
if (this.pathWithSubFolders[index]) {
- if (path.startsWith(scopePath)) {
+ // TODO (frederic) apply similar change also if not looking at subfolders
+ int pathLength = path.length();
+ int scopeLength = scopePath.length();
+ if (pathLength < scopeLength) {
+ return false;
+ }
+ if (scopeLength == 0) {
return true;
}
+ if (pathLength == scopeLength) {
+ return path.equals(scopePath);
+ }
+ if (path.startsWith(scopePath)) {
+ if (scopePath.charAt(scopeLength-1) == '/') scopeLength--;
+ return path.charAt(scopeLength) == '/';
+ }
} else {
// if not looking at subfolders, this scope encloses the given path
// if this path is a direct child of the scope's ressource
@@ -336,8 +362,9 @@
IPackageFragmentRoot root = (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
if (root != null && root.isArchive()) {
IPath rootPath = root.getPath();
+ String rootPathToString = rootPath.getDevice() == null ? rootPath.toString() : rootPath.toOSString();
IPath relativePath = getPath(element, true/*relative path*/);
- return indexOf(relativePath.toString(), rootPath.toString()) >= 0;
+ return indexOf(relativePath.toString(), rootPathToString) >= 0;
}
return this.indexOf(getPath(element, false/*full path*/).toString(), null) >= 0;
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java
index 0b90852..ea4b7da 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java
@@ -30,18 +30,6 @@
protected boolean needsInitialize;
-private static JavaWorkspaceScope TheWorkspaceScope = null;
-
-public static JavaWorkspaceScope createScope() {
- if (TheWorkspaceScope == null)
- TheWorkspaceScope = new JavaWorkspaceScope();
-
- return TheWorkspaceScope;
-}
-
-private JavaWorkspaceScope() {
- JavaModelManager.getJavaModelManager().rememberScope(this);
-}
public boolean encloses(IJavaElement element) {
/*
if (this.needsInitialize) {
@@ -119,10 +107,16 @@
this.needsInitialize = true;
break;
case IJavaElementDelta.CHANGED:
- children = delta.getAffectedChildren();
- for (int i = 0, length = children.length; i < length; i++) {
- IJavaElementDelta child = children[i];
- this.processDelta(child);
+ int flags = delta.getFlags();
+ if ((flags & IJavaElementDelta.F_CLOSED) != 0
+ || (flags & IJavaElementDelta.F_OPENED) != 0) {
+ this.needsInitialize = true;
+ } else {
+ children = delta.getAffectedChildren();
+ for (int i = 0, length = children.length; i < length; i++) {
+ IJavaElementDelta child = children[i];
+ this.processDelta(child);
+ }
}
break;
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java
index 1957109..ec22707 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java
@@ -80,6 +80,9 @@
char[] simpleTypeName = CharOperation.lastSegment(typeName,'.');
addTypeReference(simpleTypeName);
addIndexEntry(CONSTRUCTOR_REF, ConstructorPattern.createIndexKey(simpleTypeName, argCount));
+ char[] innermostTypeName = CharOperation.lastSegment(simpleTypeName,'$');
+ if (innermostTypeName != simpleTypeName)
+ addIndexEntry(CONSTRUCTOR_REF, ConstructorPattern.createIndexKey(innermostTypeName, argCount));
}
public void addEnumDeclaration(int modifiers, char[] packageName, char[] name, char[][] enclosingTypeNames, char[][] superinterfaces) {
addIndexEntry(TYPE_DECL, TypeDeclarationPattern.createIndexKey(modifiers, name, packageName, enclosingTypeNames));
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java
index eba9567..b4ee43a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core.search.indexing;
+import org.eclipse.jdt.core.search.IJavaSearchConstants;
+
public interface IIndexConstants {
/* index encoding */
@@ -31,6 +33,8 @@
char ENUM_SUFFIX = 'E';
char ANNOTATION_TYPE_SUFFIX = 'A';
char TYPE_SUFFIX = 0;
+ char CLASS_AND_ENUM_SUFFIX = IJavaSearchConstants.CLASS_AND_ENUM;
+ char CLASS_AND_INTERFACE_SUFFIX = IJavaSearchConstants.CLASS_AND_INTERFACE;
char SEPARATOR= '/';
char[] ONE_STAR = new char[] {'*'};
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
index fb4c740..31ace01 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
@@ -189,18 +189,19 @@
}
// index isn't cached, consider reusing an existing index file
+ String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
if (reuseExistingFile) {
File indexFile = new File(indexLocation);
if (indexFile.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing
try {
- index = new Index(indexLocation, containerPath.toString(), true /*reuse index file*/); //$NON-NLS-1$
+ index = new Index(indexLocation, containerPathString, true /*reuse index file*/); //$NON-NLS-1$
indexes.put(indexLocation, index);
return index;
} catch (IOException e) {
// failed to read the existing file or its no longer compatible
if (currentIndexState != REBUILDING_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt
if (VERBOSE)
- Util.verbose("-> cannot reuse existing index: "+indexLocation+" path: "+containerPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+ Util.verbose("-> cannot reuse existing index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
rebuildIndex(indexLocation, containerPath);
return null;
}
@@ -216,13 +217,13 @@
if (createIfMissing) {
try {
if (VERBOSE)
- Util.verbose("-> create empty index: "+indexLocation+" path: "+containerPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
- index = new Index(indexLocation, containerPath.toString(), false /*do not reuse index file*/); //$NON-NLS-1$
+ Util.verbose("-> create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
+ index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/); //$NON-NLS-1$
indexes.put(indexLocation, index);
return index;
} catch (IOException e) {
if (VERBOSE)
- Util.verbose("-> unable to create empty index: "+indexLocation+" path: "+containerPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+ Util.verbose("-> unable to create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
// The file could not be created. Possible reason: the project has been deleted.
return null;
}
@@ -423,6 +424,7 @@
*/
public synchronized Index recreateIndex(IPath containerPath) {
// only called to over write an existing cached index...
+ String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
try {
// Path is already canonical
String indexLocation = computeIndexLocation(containerPath);
@@ -431,15 +433,15 @@
ReadWriteMonitor monitor = index == null ? null : index.monitor;
if (VERBOSE)
- Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
- index = new Index(indexLocation, containerPath.toString(), false /*reuse index file*/); //$NON-NLS-1$
+ Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
+ index = new Index(indexLocation, containerPathString, false /*reuse index file*/); //$NON-NLS-1$
this.indexes.put(indexLocation, index);
index.monitor = monitor;
return index;
} catch (IOException e) {
// The file could not be created. Possible reason: the project has been deleted.
if (VERBOSE) {
- Util.verbose("-> failed to recreate index for path: "+containerPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+ Util.verbose("-> failed to recreate index for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
e.printStackTrace();
}
return null;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java
index f386716..8feb299 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java
@@ -36,6 +36,9 @@
* @see ISourceElementRequestor#acceptConstructorReference(char[], int, int)
*/
public void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition) {
+ if (CharOperation.indexOf(Signature.C_GENERIC_START, typeName) > 0) {
+ typeName = Signature.toCharArray(Signature.getTypeErasure(Signature.createTypeSignature(typeName, false)).toCharArray());
+ }
this.indexer.addConstructorReference(typeName, argCount);
int lastDot = CharOperation.lastIndexOf('.', typeName);
if (lastDot != -1) {
@@ -142,15 +145,15 @@
private void enterClass(TypeInfo typeInfo) {
// eliminate possible qualifications, given they need to be fully resolved again
- if (typeInfo.superclass != null){
- typeInfo.superclass = CharOperation.lastSegment(typeInfo.superclass, '.');
+ if (typeInfo.superclass != null) {
+ typeInfo.superclass = getSimpleName(typeInfo.superclass);
// add implicit constructor reference to default constructor
this.indexer.addConstructorReference(typeInfo.superclass, 0);
}
if (typeInfo.superinterfaces != null){
- for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){
- typeInfo.superinterfaces[i] = CharOperation.lastSegment(typeInfo.superinterfaces[i], '.');
+ for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++) {
+ typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
}
}
char[][] typeNames;
@@ -188,7 +191,7 @@
// eliminate possible qualifications, given they need to be fully resolved again
if (typeInfo.superinterfaces != null){
for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){
- typeInfo.superinterfaces[i] = CharOperation.lastSegment(typeInfo.superinterfaces[i], '.');
+ typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
}
}
char[][] typeNames;
@@ -217,7 +220,7 @@
// eliminate possible qualifications, given they need to be fully resolved again
if (typeInfo.superinterfaces != null){
for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){
- typeInfo.superinterfaces[i] = CharOperation.lastSegment(typeInfo.superinterfaces[i], '.');
+ typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
}
}
char[][] typeNames;
@@ -302,6 +305,38 @@
public void exitType(int declarationEnd) {
popTypeName();
}
+/*
+ * Returns the unqualified name without parameters from the given type name.
+ */
+private char[] getSimpleName(char[] typeName) {
+ int lastDot = -1, lastGenericStart = -1;
+ int depthCount = 0;
+ int length = typeName.length;
+ lastDotLookup: for (int i = length -1; i >= 0; i--) {
+ switch (typeName[i]) {
+ case '.':
+ if (depthCount == 0) {
+ lastDot = i;
+ break lastDotLookup;
+ }
+ break;
+ case '<':
+ depthCount--;
+ if (depthCount == 0) lastGenericStart = i;
+ break;
+ case '>':
+ depthCount++;
+ break;
+ }
+ }
+ if (lastGenericStart < 0) {
+ if (lastDot < 0) {
+ return typeName;
+ }
+ return CharOperation.subarray(typeName, lastDot + 1, length);
+ }
+ return CharOperation.subarray(typeName, lastDot + 1, lastGenericStart);
+}
public void popTypeName() {
if (depth > 0) {
enclosingTypeNames[--depth] = null;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java
index ea70f40..64703bd 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java
@@ -246,15 +246,20 @@
if (!checkTypeName(pattern.simpleName, patternString, fullyQualifiedTypeName, pattern.isCaseSensitive())) return false;
}
+ int kind = type.getKind();
switch (pattern.typeSuffix) {
case CLASS_SUFFIX:
- return type.getKind() == IGenericType.CLASS_DECL;
+ return kind == IGenericType.CLASS_DECL;
case INTERFACE_SUFFIX:
- return type.getKind() == IGenericType.INTERFACE_DECL;
+ return kind == IGenericType.INTERFACE_DECL;
case ENUM_SUFFIX:
- return type.getKind() == IGenericType.ENUM_DECL;
+ return kind == IGenericType.ENUM_DECL;
case ANNOTATION_TYPE_SUFFIX:
- return type.getKind() == IGenericType.ANNOTATION_TYPE_DECL;
+ return kind == IGenericType.ANNOTATION_TYPE_DECL;
+ case CLASS_AND_INTERFACE_SUFFIX:
+ return kind == IGenericType.CLASS_DECL || kind == IGenericType.INTERFACE_DECL;
+ case CLASS_AND_ENUM_SUFFIX:
+ return kind == IGenericType.CLASS_DECL || kind == IGenericType.ENUM_DECL;
case TYPE_SUFFIX: // nothing
}
return true;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java
index 040cceb..d6a9f10 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java
@@ -140,4 +140,9 @@
public String toString() {
return "Source classpath directory " + sourceFolder.getFullPath().toString(); //$NON-NLS-1$
}
+
+public String debugPathString() {
+ return this.sourceLocation;
+}
+
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java
index 731521d..de41665 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java
@@ -343,8 +343,14 @@
ExplicitConstructorCall constructorCall = constructor.constructorCall;
if (constructorCall != null && constructorCall.accessMode == ExplicitConstructorCall.ImplicitSuper) {
// eliminate explicit super call as it will be treated with matchLevel(ExplicitConstructorCall, boolean)
- referencesLevel = resolveLevel(constructorCall.binding);
- if (referencesLevel == ACCURATE_MATCH) return ACCURATE_MATCH; // cannot get better
+ int callCount = (constructorCall.arguments == null) ? 0 : constructorCall.arguments.length;
+ int patternCount = (this.pattern.parameterSimpleNames == null) ? 0 : this.pattern.parameterSimpleNames.length;
+ if (patternCount != callCount) {
+ referencesLevel = IMPOSSIBLE_MATCH;
+ } else {
+ referencesLevel = resolveLevel(constructorCall.binding);
+ if (referencesLevel == ACCURATE_MATCH) return ACCURATE_MATCH; // cannot get better
+ }
}
}
if (!checkDeclarations) return referencesLevel;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java
index 1e6c055..ac3eb02 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java
@@ -121,9 +121,9 @@
// Get unique key for parameterized constructors
String genericDeclaringTypeSignature = null;
- BindingKey key;
- if (method.isResolved() && (key = new BindingKey(method.getKey())).isParameterizedType()) {
- genericDeclaringTypeSignature = key.getDeclaringTypeSignature();
+ String key;
+ if (method.isResolved() && new BindingKey(key = method.getKey()).isParameterizedType()) {
+ genericDeclaringTypeSignature = Util.getDeclaringTypeSignature(key);
} else {
constructorParameters = true;
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java
index 6c5e12d..5904f2c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java
@@ -342,11 +342,15 @@
*/
protected int resolveLevelForType(TypeBinding typeBinding) {
FieldPattern fieldPattern = (FieldPattern) this.pattern;
+ TypeBinding fieldTypeBinding = typeBinding;
+ if (fieldTypeBinding != null && fieldTypeBinding.isParameterizedType()) {
+ fieldTypeBinding = typeBinding.erasure();
+ }
return resolveLevelForType(
fieldPattern.typeSimpleName,
fieldPattern.typeQualification,
fieldPattern.getTypeArguments(),
0,
- typeBinding);
+ fieldTypeBinding);
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java
index b5edcd7..c1bf7b7 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java
@@ -242,7 +242,7 @@
void storeTypeSignaturesAndArguments(IType type) {
BindingKey key;
if (type.isResolved() && (key = new BindingKey(type.getKey())).isParameterizedType()) {
- String signature = key.toSignature();
+ String signature = key.internalToSignature();
this.typeSignatures = Util.splitTypeLevelsSignature(signature);
setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
} else {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index 219672c..ca99465 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -13,6 +13,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.zip.ZipFile;
@@ -38,6 +39,7 @@
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.*;
@@ -65,6 +67,7 @@
import org.eclipse.jdt.internal.core.PackageFragmentRoot;
import org.eclipse.jdt.internal.core.SearchableEnvironment;
import org.eclipse.jdt.internal.core.SourceMapper;
+import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
import org.eclipse.jdt.internal.core.index.Index;
import org.eclipse.jdt.internal.core.search.*;
@@ -118,6 +121,9 @@
CompilationUnitScope unitScope;
SimpleLookupTable bindings;
+// Cache for method handles
+HashSet methodHandles;
+
/**
* An ast visitor that visits local type declarations.
*/
@@ -146,21 +152,11 @@
occurrenceCount = occurrenceCount + 1;
}
occurrencesCounts.put(simpleName, occurrenceCount);
- if (typeDeclaration.allocation == null || typeDeclaration.allocation.enumConstant == null) {
- if ((typeDeclaration.bits & ASTNode.IsAnonymousTypeMASK) != 0) {
- reportMatching(typeDeclaration, this.enclosingElement, -1, nodeSet, occurrenceCount);
- } else {
- Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeDeclaration);
- reportMatching(typeDeclaration, this.enclosingElement, level != null ? level.intValue() : -1, nodeSet, occurrenceCount);
- }
+ if ((typeDeclaration.bits & ASTNode.IsAnonymousTypeMASK) != 0) {
+ reportMatching(typeDeclaration, this.enclosingElement, -1, nodeSet, occurrenceCount);
} else {
Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeDeclaration);
- if (level != null) {
- FieldDeclaration enumConstant = typeDeclaration.allocation.enumConstant;
- int offset = enumConstant.sourceStart;
- SearchMatch match = newDeclarationMatch(this.enclosingElement, this.enclosingElementBinding, level.intValue(), offset, enumConstant.sourceEnd-offset+1);
- report(match);
- }
+ reportMatching(typeDeclaration, this.enclosingElement, level != null ? level.intValue() : -1, nodeSet, occurrenceCount);
}
return false; // don't visit members as this was done during reportMatching(...)
} catch (CoreException e) {
@@ -406,36 +402,6 @@
}
return this.basicParser;
}
-/**
- * Add the possibleMatch to the loop
- * -> build compilation unit declarations, their bindings and record their results.
- */
-protected void parseAndBuildBindings(PossibleMatch possibleMatch, boolean mustResolve) {
- if (this.progressMonitor != null && this.progressMonitor.isCanceled())
- throw new OperationCanceledException();
-
- try {
- if (BasicSearchEngine.VERBOSE)
- System.out.println("Parsing " + possibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$
-
- this.parser.nodeSet = possibleMatch.nodeSet;
- CompilationResult unitResult = new CompilationResult(possibleMatch, 1, 1, this.options.maxProblemsPerUnit);
- CompilationUnitDeclaration parsedUnit = this.parser.dietParse(possibleMatch, unitResult);
- if (parsedUnit != null) {
- if (mustResolve && !parsedUnit.isEmpty())
- this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
-
- // add the possibleMatch with its parsedUnit to matchesToProcess
- possibleMatch.parsedUnit = parsedUnit;
- int size = this.matchesToProcess.length;
- if (this.numberOfMatches == size)
- System.arraycopy(this.matchesToProcess, 0, this.matchesToProcess = new PossibleMatch[size == 0 ? 1 : size * 2], 0, this.numberOfMatches);
- this.matchesToProcess[this.numberOfMatches++] = possibleMatch;
- }
- } finally {
- this.parser.nodeSet = null;
- }
-}
/*
* Caches the given binary type in the lookup environment and returns it.
* Returns the existing one if already cached.
@@ -515,7 +481,9 @@
IBinaryMethod binaryMethod = methods[i];
char[] selector = binaryMethod.isConstructor() ? type.getElementName().toCharArray() : binaryMethod.getSelector();
if (CharOperation.equals(selector, method.selector)) {
- char[][] parameterTypes = Signature.getParameterTypes(binaryMethod.getMethodDescriptor());
+ char[] signature = binaryMethod.getGenericSignature();
+ if (signature == null) signature = binaryMethod.getMethodDescriptor();
+ char[][] parameterTypes = Signature.getParameterTypes(signature);
if (argCount != parameterTypes.length) continue nextMethod;
for (int j = 0; j < argCount; j++) {
char[] typeName;
@@ -528,11 +496,11 @@
typeName = CharOperation.concat(typeName, new char[] {'[', ']'});
}
char[] parameterTypeName = ClassFileMatchLocator.convertClassFileFormat(parameterTypes[j]);
- if (!CharOperation.endsWith(Signature.toCharArray(parameterTypeName), typeName))
+ if (!CharOperation.endsWith(Signature.toCharArray(Signature.getTypeErasure(parameterTypeName)), typeName))
continue nextMethod;
parameterTypes[j] = parameterTypeName;
}
- return type.getMethod(new String(selector), CharOperation.toStrings(parameterTypes));
+ return createMethodHandle(type, new String(selector), CharOperation.toStrings(parameterTypes));
}
}
}
@@ -548,19 +516,41 @@
// typeName = CharOperation.concat(typeName, new char[] {'[', ']'});
parameterTypeSignatures[i] = Signature.createTypeSignature(typeName, false);
}
- return type.getMethod(new String(method.selector), parameterTypeSignatures);
+
+ return createMethodHandle(type, new String(method.selector), parameterTypeSignatures);
+}
+
+/*
+ * Create method handle.
+ * Store occurences for create handle to retrieve possible duplicate ones.
+ */
+private IJavaElement createMethodHandle(IType type, String methodName, String[] parameterTypeSignatures) {
+ IMethod methodHandle = type.getMethod(methodName, parameterTypeSignatures);
+ if (methodHandle instanceof SourceMethod) {
+ while (this.methodHandles.contains(methodHandle)) {
+ ((SourceMethod) methodHandle).occurrenceCount++;
+ }
+ }
+ this.methodHandles.add(methodHandle);
+ return methodHandle;
}
/**
* Creates an IField from the given field declaration and type.
*/
protected IJavaElement createHandle(FieldDeclaration fieldDeclaration, TypeDeclaration typeDeclaration, IJavaElement parent) {
if (!(parent instanceof IType)) return parent;
+ IType type = (IType) parent;
switch (fieldDeclaration.getKind()) {
case AbstractVariableDeclaration.FIELD :
case AbstractVariableDeclaration.ENUM_CONSTANT :
return ((IType) parent).getField(new String(fieldDeclaration.name));
}
+ if (type.isBinary()) {
+ // do not return initializer for binary types
+ // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=98378
+ return type;
+ }
// find occurence count of the given initializer in its type declaration
int occurrenceCount = 0;
FieldDeclaration[] fields = typeDeclaration.fields;
@@ -623,6 +613,19 @@
return createTypeHandle(typeName.substring(0, lastDollar));
}
/**
+ * Creates an IImportDeclaration from the given import statement
+ */
+protected IJavaElement createPackageDeclarationHandle(CompilationUnitDeclaration unit) {
+ if (unit.isPackageInfo()) {
+ char[] packName = CharOperation.concatWith(unit.currentPackage.getImportName(), '.');
+ Openable openable = this.currentPossibleMatch.openable;
+ if (openable instanceof CompilationUnit) {
+ return ((CompilationUnit) openable).getPackageDeclaration(new String(packName));
+ }
+ }
+ return createTypeHandle(new String(unit.getMainTypeName()));
+}
+/**
* Creates an IType from the given simple top level type name.
*/
protected IType createTypeHandle(String simpleTypeName) {
@@ -719,7 +722,7 @@
protected IType getFocusType() {
return this.scope instanceof HierarchyScope ? ((HierarchyScope) this.scope).focusType : null;
}
-protected void getMethodBodies(CompilationUnitDeclaration unit) {
+protected void getMethodBodies(CompilationUnitDeclaration unit, MatchingNodeSet nodeSet) {
if (unit.ignoreMethodBodies) {
unit.ignoreFurtherInvestigation = true;
return; // if initial diet parse did not work, no need to dig into method bodies.
@@ -738,7 +741,7 @@
char[] contents = compilationResult.compilationUnit.getContents();
this.parser.javadocParser.scanner.setSource(contents);
}
- this.parser.nodeSet = this.currentPossibleMatch.nodeSet;
+ this.parser.nodeSet = nodeSet;
this.parser.parseBodies(unit);
} finally {
this.parser.nodeSet = null;
@@ -763,31 +766,32 @@
this.bindings.put(typeKey, typeBinding);
return typeBinding.isValidBinding() ? typeBinding : null;
}
-public MethodBinding getMethodBinding(IMethod method) {
+public MethodBinding getMethodBinding(MethodPattern methodPattern) {
if (this.unitScope == null) return null;
// Try to get binding from cache
- Binding binding = (Binding) this.bindings.get(method);
+ Binding binding = (Binding) this.bindings.get(methodPattern);
if (binding != null) {
if (binding instanceof MethodBinding && binding.isValidBinding())
return (MethodBinding) binding;
return null;
}
// Get binding from unit scope
- String typeName = method.getDeclaringType().getElementName();
- TypeBinding declaringTypeBinding = getType(typeName, typeName.toCharArray());
+ char[] typeName = PatternLocator.qualifiedPattern(methodPattern.declaringSimpleName, methodPattern.declaringQualification);
+ if (typeName == null) {
+ if (methodPattern.declaringType == null) return null;
+ typeName = methodPattern.declaringType.getFullyQualifiedName().toCharArray();
+ }
+ TypeBinding declaringTypeBinding = getType(typeName, typeName);
if (declaringTypeBinding != null) {
if (declaringTypeBinding.isArrayType()) {
declaringTypeBinding = declaringTypeBinding.leafComponentType();
}
if (!declaringTypeBinding.isBaseType()) {
- String[] parameterTypes = method.getParameterTypes();
+ char[][] parameterTypes = methodPattern.parameterSimpleNames;
+ if (parameterTypes == null) return null;
int paramTypeslength = parameterTypes.length;
- char[][] paramTypesChars = new char[paramTypeslength][];
- for (int i=0; i<paramTypeslength; i++) {
- paramTypesChars[i] = Signature.toCharArray(parameterTypes[i].toCharArray());
- }
ReferenceBinding referenceBinding = (ReferenceBinding) declaringTypeBinding;
- MethodBinding[] methods = referenceBinding.getMethods(method.getElementName().toCharArray());
+ MethodBinding[] methods = referenceBinding.getMethods(methodPattern.selector);
int methodsLength = methods.length;
TypeVariableBinding[] refTypeVariables = referenceBinding.typeVariables();
int typeVarLength = refTypeVariables==null ? 0 : refTypeVariables.length;
@@ -796,42 +800,43 @@
int paramLength = methodParameters==null ? 0 : methodParameters.length;
TypeVariableBinding[] methodTypeVariables = methods[i].typeVariables;
int methTypeVarLength = methodTypeVariables==null ? 0 : methodTypeVariables.length;
- boolean found = paramLength == paramTypeslength;
- if (found) {
- for (int p=0; found && p<paramLength; p++) {
- if (CharOperation.equals(methodParameters[p].erasure().shortReadableName(), paramTypesChars[p])) {
+ boolean found = false;
+ if (paramLength == paramTypeslength) {
+ for (int p=0; p<paramLength; p++) {
+ if (CharOperation.equals(methodParameters[p].sourceName(), parameterTypes[p])) {
// param erasure match
+ found = true;
} else {
// type variable
- boolean foundVar = true;
- for (int v=0; foundVar && v<typeVarLength; v++) {
- if (!CharOperation.equals(refTypeVariables[v].sourceName, paramTypesChars[p])) {
- foundVar = false;
+ found = false;
+ for (int v=0; v<typeVarLength; v++) {
+ if (!CharOperation.equals(refTypeVariables[v].sourceName, parameterTypes[p])) {
+ found = false;
+ break;
}
+ found = true;
}
- if (!foundVar) {
- foundVar = true;
- for (int v=0; foundVar && v<methTypeVarLength; v++) {
- if (!CharOperation.equals(methodTypeVariables[v].sourceName, paramTypesChars[p])) {
- foundVar = false;
+ if (!found) {
+ for (int v=0; v<methTypeVarLength; v++) {
+ if (!CharOperation.equals(methodTypeVariables[v].sourceName, parameterTypes[p])) {
+ found = false;
+ break;
}
+ found = true;
}
- if (!foundVar) found = false;
}
+ if (!found) break;
}
}
}
if (found) {
- this.bindings.put(method, methods[i]);
+ this.bindings.put(methodPattern, methods[i]);
return methods[i];
}
}
-// methodBinding = referenceBinding.getExactMethod(method.getElementName().toCharArray(), parameters);
-// this.bindings.put(method, methodBinding);
-// return methodBinding;
}
}
- this.bindings.put(method, new ProblemMethodBinding(method.getElementName().toCharArray(), null, ProblemReasons.NotFound));
+ this.bindings.put(methodPattern, new ProblemMethodBinding(methodPattern.selector, null, ProblemReasons.NotFound));
return null;
}
protected boolean hasAlreadyDefinedType(CompilationUnitDeclaration parsedUnit) {
@@ -884,22 +889,43 @@
initialize(javaProject, length);
// create and resolve binding (equivalent to beginCompilation() in Compiler)
- boolean mustResolve = ((InternalSearchPattern)this.pattern).mustResolve;
+ boolean mustResolvePattern = ((InternalSearchPattern)this.pattern).mustResolve;
+ boolean mustResolve = mustResolvePattern;
+ this.patternLocator.mayBeGeneric = this.options.sourceLevel >= ClassFileConstants.JDK1_5;
boolean bindingsWereCreated = mustResolve;
try {
for (int i = start, maxUnits = start + length; i < maxUnits; i++) {
PossibleMatch possibleMatch = possibleMatches[i];
try {
- parseAndBuildBindings(possibleMatch, mustResolve);
- if (!mustResolve) {
+ if (!parseAndBuildBindings(possibleMatch, mustResolvePattern)) continue;
+ // Currently we only need to resolve over pattern flag if there's potential parameterized types
+ if (this.patternLocator.mayBeGeneric) {
+ // If pattern does not resolve then rely on possible match node set resolution
+ // which may have been modified while locator was adding possible matches to it
+ if (!mustResolvePattern && !mustResolve) {
+ mustResolve = possibleMatch.nodeSet.mustResolve;
+ bindingsWereCreated = mustResolve;
+ }
+ } else {
+ // Reset matching node resolution with pattern one if there's no potential parameterized type
+ // to minimize side effect on previous search behavior
+ possibleMatch.nodeSet.mustResolve = mustResolvePattern;
+ }
+ // possible match node resolution has been merged with pattern one, so rely on it to know
+ // whether we need to process compilation unit now or later
+ if (!possibleMatch.nodeSet.mustResolve) {
if (this.progressMonitor != null) {
this.progressWorked++;
if ((this.progressWorked%this.progressStep)==0) this.progressMonitor.worked(this.progressStep);
}
process(possibleMatch, bindingsWereCreated);
+ if (this.numberOfMatches>0 && this.matchesToProcess[this.numberOfMatches-1] == possibleMatch) {
+ // forget last possible match as it was processed
+ this.numberOfMatches--;
+ }
}
} finally {
- if (!mustResolve)
+ if (!possibleMatch.nodeSet.mustResolve)
possibleMatch.cleanUp();
}
}
@@ -1081,7 +1107,7 @@
}
previousJavaProject = javaProject;
}
- matchSet.add(new PossibleMatch(this, resource, openable, searchDocument));
+ matchSet.add(new PossibleMatch(this, resource, openable, searchDocument, ((InternalSearchPattern) this.pattern).mustResolve));
}
// last project
@@ -1100,6 +1126,7 @@
this.nameEnvironment.cleanup();
manager.flushZipFiles();
this.bindings = null;
+ this.patternLocator.clear();
}
}
/**
@@ -1120,7 +1147,7 @@
IJavaElement focus = ((InternalSearchPattern) searchPattern).focus;
if (focus != null) {
SearchDocument document = participant.getDocument(focus.getPath().toString());
- this.currentPossibleMatch = new PossibleMatch(this, focus.getResource(), null, document);
+ this.currentPossibleMatch = new PossibleMatch(this, focus.getResource(), null, document, ((InternalSearchPattern) searchPattern).mustResolve);
if (encloses(focus)) {
SearchMatch match = newDeclarationMatch(focus.getAncestor(IJavaElement.PACKAGE_FRAGMENT), null/*no binding*/, SearchMatch.A_ACCURATE, -1, -1);
report(match);
@@ -1161,7 +1188,7 @@
if (resource == null) // case of a file in an external jar
resource = javaProject.getProject();
SearchDocument document = participant.getDocument(resource.getFullPath().toString());
- this.currentPossibleMatch = new PossibleMatch(this, resource, null, document);
+ this.currentPossibleMatch = new PossibleMatch(this, resource, null, document, ((InternalSearchPattern) searchPattern).mustResolve);
try {
if (encloses(pkg)) {
SearchMatch match = newDeclarationMatch(pkg, null/*no binding*/, SearchMatch.A_ACCURATE, -1, -1);
@@ -1360,6 +1387,47 @@
return newTypeReferenceMatch(enclosingElement, enclosingBinding, accuracy, reference.sourceStart, reference.sourceEnd-reference.sourceStart+1, reference);
}
+/**
+ * Add the possibleMatch to the loop
+ * -> build compilation unit declarations, their bindings and record their results.
+ */
+protected boolean parseAndBuildBindings(PossibleMatch possibleMatch, boolean mustResolve) throws CoreException {
+ if (this.progressMonitor != null && this.progressMonitor.isCanceled())
+ throw new OperationCanceledException();
+
+ try {
+ if (BasicSearchEngine.VERBOSE)
+ System.out.println("Parsing " + possibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$
+
+ this.parser.nodeSet = possibleMatch.nodeSet;
+ CompilationResult unitResult = new CompilationResult(possibleMatch, 1, 1, this.options.maxProblemsPerUnit);
+ CompilationUnitDeclaration parsedUnit = this.parser.dietParse(possibleMatch, unitResult);
+ if (parsedUnit != null) {
+ if (!parsedUnit.isEmpty()) {
+ if (mustResolve) {
+ this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+ }
+ if (hasAlreadyDefinedType(parsedUnit)) return false; // skip type has it is hidden so not visible
+ getMethodBodies(parsedUnit, possibleMatch.nodeSet);
+ if (this.patternLocator.mayBeGeneric && !mustResolve && possibleMatch.nodeSet.mustResolve) {
+ // special case: possible match node set force resolution although pattern does not
+ // => we need to build types for this compilation unit
+ this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+ }
+ }
+
+ // add the possibleMatch with its parsedUnit to matchesToProcess
+ possibleMatch.parsedUnit = parsedUnit;
+ int size = this.matchesToProcess.length;
+ if (this.numberOfMatches == size)
+ System.arraycopy(this.matchesToProcess, 0, this.matchesToProcess = new PossibleMatch[size == 0 ? 1 : size * 2], 0, this.numberOfMatches);
+ this.matchesToProcess[this.numberOfMatches++] = possibleMatch;
+ }
+ } finally {
+ this.parser.nodeSet = null;
+ }
+ return true;
+}
/*
* Process a compilation unit already parsed and build.
*/
@@ -1378,26 +1446,31 @@
}
if (hasAlreadyDefinedType(unit)) return; // skip type has it is hidden so not visible
- getMethodBodies(unit);
+ // Move getMethodBodies to #parseAndBuildings(...) method to allow possible match resolution management
+ //getMethodBodies(unit);
- if (bindingsWereCreated && ((InternalSearchPattern)this.pattern).mustResolve && unit.types != null) {
- if (BasicSearchEngine.VERBOSE)
- System.out.println("Resolving " + this.currentPossibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$
-
- reduceParseTree(unit);
-
- if (unit.scope != null) {
- // fault in fields & methods
- unit.scope.faultInTypes();
+ boolean mustResolve = ((InternalSearchPattern)this.pattern).mustResolve || possibleMatch.nodeSet.mustResolve;
+ if (bindingsWereCreated && mustResolve) {
+ if (unit.types != null) {
+ if (BasicSearchEngine.VERBOSE)
+ System.out.println("Resolving " + this.currentPossibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$
+
+ reduceParseTree(unit);
+
+ if (unit.scope != null) {
+ // fault in fields & methods
+ unit.scope.faultInTypes();
+ }
+ unit.resolve();
+ } else if (unit.isPackageInfo()) {
+ if (BasicSearchEngine.VERBOSE)
+ System.out.println("Resolving " + this.currentPossibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$
+ unit.resolve();
}
- unit.resolve();
-
- reportMatching(unit, true);
- } else {
- reportMatching(unit, ((InternalSearchPattern)this.pattern).mustResolve);
}
+ reportMatching(unit, mustResolve);
} catch (AbortCompilation e) {
- // could not resolve: report innacurate matches
+ // could not resolve: report inaccurate matches
reportMatching(unit, true); // was partially resolved
if (!(e instanceof AbortCompilationUnit)) {
// problem with class path
@@ -1453,11 +1526,21 @@
System.out.println("Reporting match"); //$NON-NLS-1$
System.out.println("\tResource: " + match.getResource()); //$NON-NLS-2$//$NON-NLS-1$
System.out.println("\tPositions: [offset=" + match.getOffset() + ", length=" + match.getLength() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- if (this.parser != null && match.getOffset() > 0 && match.getLength() > 0 && !(match.getElement() instanceof BinaryMember)) {
- String selection = new String(this.parser.scanner.source, match.getOffset(), match.getLength());
- System.out.println("\tSelection: -->" + selection + "<--"); //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ if (this.parser != null && match.getOffset() > 0 && match.getLength() > 0 && !(match.getElement() instanceof BinaryMember)) {
+ String selection = new String(this.parser.scanner.source, match.getOffset(), match.getLength());
+ System.out.println("\tSelection: -->" + selection + "<--"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } catch (Exception e) {
+ // it's just for debug purposes... ignore all exceptions in this area
}
- System.out.println("\tJava element: " + ((JavaElement)match.getElement()).toStringWithAncestors()); //$NON-NLS-1$
+ try {
+ JavaElement javaElement = (JavaElement)match.getElement();
+ System.out.println("\tJava element: "+ javaElement.toStringWithAncestors()); //$NON-NLS-1$
+ if (!javaElement.exists()) System.out.println("\t\tWARNING: this element does NOT exist!"); //$NON-NLS-1$
+ } catch (Exception e) {
+ // it's just for debug purposes... ignore all exceptions in this area
+ }
System.out.println(match.getAccuracy() == SearchMatch.A_ACCURATE
? "\tAccuracy: EXACT_MATCH" //$NON-NLS-1$
: "\tAccuracy: POTENTIAL_MATCH"); //$NON-NLS-1$
@@ -1748,7 +1831,7 @@
if (encloses(enclosingElement)) {
int length = scanner.currentPosition - nameSourceStart;
SearchMatch match = this.patternLocator.newDeclarationMatch(method, enclosingElement, method.binding, accuracy, length, this);
- report(match);
+ if (match != null) report(match);
}
}
}
@@ -1767,15 +1850,10 @@
// report annotations
if (method.annotations != null) {
- for (int i=0, al=method.annotations.length; i<al; i++) {
- TypeReference typeRef = method.annotations[i].type;
- Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeRef);
- if (level != null) {
- if (enclosingElement == null)
- enclosingElement = createHandle(method, parent);
- this.patternLocator.matchReportReference(typeRef, enclosingElement, method.binding, level.intValue(), this);
- }
+ if (enclosingElement == null) {
+ enclosingElement = createHandle(method, parent);
}
+ reportMatching(method.annotations, enclosingElement, method.binding, nodeSet, true, true);
}
// references in this method
@@ -1800,10 +1878,66 @@
}
}
/**
+ * Report matching in annotations.
+ */
+protected void reportMatching(Annotation[] annotations, IJavaElement enclosingElement, Binding elementBinding, MatchingNodeSet nodeSet, boolean matchedContainer, boolean enclosesElement) throws CoreException {
+ for (int i=0, al=annotations.length; i<al; i++) {
+ Annotation annotationType = annotations[i];
+
+ // Look for annotation type ref
+ TypeReference typeRef = annotationType.type;
+ Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeRef);
+ if (level != null && matchedContainer) {
+ this.patternLocator.matchReportReference(typeRef, enclosingElement, elementBinding, level.intValue(), this);
+ }
+
+ // Look for attribute ref
+ MemberValuePair[] pairs = annotationType.memberValuePairs();
+ for (int j = 0, pl = pairs.length; j < pl; j++) {
+ MemberValuePair pair = pairs[j];
+ level = (Integer) nodeSet.matchingNodes.removeKey(pair);
+ if (level != null && enclosesElement) {
+ ASTNode reference = (annotationType instanceof SingleMemberAnnotation) ? (ASTNode) annotationType: pair;
+ this.patternLocator.matchReportReference(reference, enclosingElement, pair.binding, level.intValue(), this);
+ }
+ }
+
+ // Look for reference inside annotation
+ ASTNode[] nodes = nodeSet.matchingNodes(annotationType.sourceStart, annotationType.declarationSourceEnd);
+ if (nodes != null) {
+ if (!matchedContainer) {
+ for (int j = 0, nl = nodes.length; j < nl; j++) {
+ nodeSet.matchingNodes.removeKey(nodes[j]);
+ }
+ } else {
+ for (int j = 0, nl = nodes.length; j < nl; j++) {
+ ASTNode node = nodes[j];
+ level = (Integer) nodeSet.matchingNodes.removeKey(node);
+ if (enclosesElement) {
+ this.patternLocator.matchReportReference(node, enclosingElement, elementBinding, level.intValue(), this);
+ }
+ }
+ }
+ }
+ }
+}
+/**
* Visit the given resolved parse tree and report the nodes that match the search pattern.
*/
protected void reportMatching(CompilationUnitDeclaration unit, boolean mustResolve) throws CoreException {
MatchingNodeSet nodeSet = this.currentPossibleMatch.nodeSet;
+ boolean locatorMustResolve = this.patternLocator.mustResolve;
+ if (nodeSet.mustResolve) this.patternLocator.mustResolve = true;
+ if (BasicSearchEngine.VERBOSE) {
+ System.out.println("Report matching: "); //$NON-NLS-1$
+ int size = nodeSet.matchingNodes==null ? 0 : nodeSet.matchingNodes.elementSize;
+ System.out.print(" - node set: accurate="+ size); //$NON-NLS-1$
+ size = nodeSet.possibleMatchingNodesSet==null ? 0 : nodeSet.possibleMatchingNodesSet.elementSize;
+ System.out.println(", possible="+size); //$NON-NLS-1$
+ System.out.print(" - must resolve: "+mustResolve); //$NON-NLS-1$
+ System.out.print(" (locator: "+this.patternLocator.mustResolve); //$NON-NLS-1$
+ System.out.println(", nodeSet: "+nodeSet.mustResolve+')'); //$NON-NLS-1$
+ }
if (mustResolve) {
this.unitScope= unit.scope.compilationUnitScope();
// move the possible matching nodes that exactly match the search pattern to the matching nodes set
@@ -1825,18 +1959,48 @@
nodeSet.addMatch(node, this.patternLocator.resolveLevel(node));
}
nodeSet.possibleMatchingNodesSet = new SimpleSet(3);
+ if (BasicSearchEngine.VERBOSE) {
+ int size = nodeSet.matchingNodes==null ? 0 : nodeSet.matchingNodes.elementSize;
+ System.out.print(" - node set: accurate="+size); //$NON-NLS-1$
+ size = nodeSet.possibleMatchingNodesSet==null ? 0 : nodeSet.possibleMatchingNodesSet.elementSize;
+ System.out.println(", possible="+size); //$NON-NLS-1$
+ }
} else {
this.unitScope = null;
}
if (nodeSet.matchingNodes.elementSize == 0) return; // no matching nodes were found
+ this.methodHandles = new HashSet();
boolean matchedUnitContainer = (this.matchContainer & PatternLocator.COMPILATION_UNIT_CONTAINER) != 0;
+
+ // report references in javadoc
+ if (unit.javadoc != null) {
+ ASTNode[] nodes = nodeSet.matchingNodes(unit.javadoc.sourceStart, unit.javadoc.sourceEnd);
+ if (nodes != null) {
+ if (!matchedUnitContainer) {
+ for (int i = 0, l = nodes.length; i < l; i++)
+ nodeSet.matchingNodes.removeKey(nodes[i]);
+ } else {
+ IJavaElement element = createPackageDeclarationHandle(unit);
+ for (int i = 0, l = nodes.length; i < l; i++) {
+ ASTNode node = nodes[i];
+ Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
+ if (encloses(element))
+ this.patternLocator.matchReportReference(node, element, null/*no binding*/, level.intValue(), this);
+ }
+ }
+ }
+ }
+
if (matchedUnitContainer) {
-// Currently a no-op
-// ImportReference pkg = unit.currentPackage;
-// if (pkg != null && nodeSet.matchingNodes.removeKey(pkg) != null)
-// reportPackageDeclaration(pkg);
+ ImportReference pkg = unit.currentPackage;
+ if (pkg != null && pkg.annotations != null) {
+ IJavaElement element = createPackageDeclarationHandle(unit);
+ if (element != null) {
+ reportMatching(pkg.annotations, element, null, nodeSet, true, encloses(element));
+ }
+ }
ImportReference[] imports = unit.imports;
if (imports != null) {
@@ -1859,6 +2023,10 @@
reportMatching(type, null, accuracy, nodeSet, 1);
}
}
+
+ // Clear handle cache
+ this.methodHandles = null;
+ this.patternLocator.mustResolve = locatorMustResolve;
}
/**
* Visit the given field declaration and report the nodes that match exactly the
@@ -1889,15 +2057,10 @@
// report annotations
if (field.annotations != null) {
- for (int i=0, al=field.annotations.length; i<al; i++) {
- TypeReference typeRef = field.annotations[i].type;
- Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeRef);
- if (level != null) {
- if (enclosingElement == null)
- enclosingElement = createHandle(field, type, parent);
- this.patternLocator.matchReportReference(typeRef, enclosingElement, field.binding, level.intValue(), this);
- }
+ if (enclosingElement == null) {
+ enclosingElement = createHandle(field, type, parent);
}
+ reportMatching(field.annotations, enclosingElement, field.binding, nodeSet, true, true);
}
if (typeInHierarchy) {
@@ -1915,6 +2078,13 @@
for (int i = 0, l = nodes.length; i < l; i++) {
ASTNode node = nodes[i];
Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
+ if (node instanceof TypeDeclaration) {
+ // use field declaration to report match (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=88174)
+ AllocationExpression allocation = ((TypeDeclaration)node).allocation;
+ if (allocation != null && allocation.enumConstant != null) {
+ node = field;
+ }
+ }
this.patternLocator.matchReportReference(node, enclosingElement, field.binding, level.intValue(), this);
}
}
@@ -1940,9 +2110,10 @@
enclosingElement = member.getType(new String(type.name), occurrenceCount);
}
if (enclosingElement == null) return;
+ boolean enclosesElement = encloses(enclosingElement);
// report the type declaration
- if (accuracy > -1 && encloses(enclosingElement)) {
+ if (accuracy > -1 && enclosesElement) {
int offset = type.sourceStart;
SearchMatch match = this.patternLocator.newDeclarationMatch(type, enclosingElement, type.binding, accuracy, type.sourceEnd-offset+1, this);
report(match);
@@ -1957,7 +2128,7 @@
if (typeParameter != null) {
Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter);
if (level != null && matchedClassContainer) {
- if (level.intValue() > -1 && encloses(enclosingElement)) {
+ if (level.intValue() > -1 && enclosesElement) {
int offset = typeParameter.sourceStart;
SearchMatch match = this.patternLocator.newDeclarationMatch(typeParameter, enclosingElement, type.binding, level.intValue(), typeParameter.sourceEnd-offset+1, this);
report(match);
@@ -1983,13 +2154,7 @@
// report annotations
if (type.annotations != null) {
- for (int i=0, al=type.annotations.length; i<al; i++) {
- TypeReference typeRef = type.annotations[i].type;
- Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeRef);
- if (level != null && matchedClassContainer) {
- this.patternLocator.matchReportReference(typeRef, enclosingElement, type.binding, level.intValue(), this);
- }
- }
+ reportMatching(type.annotations, enclosingElement, type.binding, nodeSet, matchedClassContainer, enclosesElement);
}
// report references in javadoc
@@ -2003,8 +2168,9 @@
for (int i = 0, l = nodes.length; i < l; i++) {
ASTNode node = nodes[i];
Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
- if (encloses(enclosingElement))
+ if (enclosesElement) {
this.patternLocator.matchReportReference(node, enclosingElement, type.binding, level.intValue(), this);
+ }
}
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
index b0d0635..775403c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
@@ -75,6 +75,10 @@
patternLocator.match(methodDeclaration, nodeSet);
return (methodDeclaration.bits & ASTNode.HasLocalTypeMASK) != 0; // continue only if it has local type
}
+ public boolean visit(AnnotationMethodDeclaration methodDeclaration, ClassScope scope) {
+ patternLocator.match(methodDeclaration, nodeSet);
+ return false; // no local type for annotation type members
+ }
}
public class ClassAndMethodDeclarationVisitor extends ClassButNoMethodDeclarationVisitor {
public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
@@ -175,13 +179,6 @@
super.classInstanceCreation(alwaysQualified);
this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
}
-protected void consumeAnnotationAsModifier() {
- super.consumeAnnotationAsModifier();
- Expression expression = this.expressionStack[this.expressionPtr];
- if (expression instanceof Annotation) {
- this.patternLocator.match(((Annotation)expression).type, this.nodeSet);
- }
-}
protected void consumeAssignment() {
super.consumeAssignment();
this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
@@ -208,30 +205,24 @@
// this is always a Reference
this.patternLocator.match((Reference) this.expressionStack[this.expressionPtr], this.nodeSet);
}
-protected void consumeInternalCompilationUnit() {
- // InternalCompilationUnit ::= PackageDeclaration
- // InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
- // InternalCompilationUnit ::= ImportDeclarations ReduceImports
-}
-protected void consumeInternalCompilationUnitWithTypes() {
- // InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
- // InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
- // InternalCompilationUnit ::= TypeDeclarations
- // InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
- // consume type declarations
- int length;
- if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
- this.compilationUnit.types = new TypeDeclaration[length];
- this.astPtr -= length;
- System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
- }
-}
protected void consumeLocalVariableDeclaration() {
super.consumeLocalVariableDeclaration();
// this is always a LocalDeclaration
this.patternLocator.match((LocalDeclaration) this.astStack[this.astPtr], this.nodeSet);
}
+protected void consumeMarkerAnnotation() {
+ super.consumeMarkerAnnotation();
+ // this is always an Annotation
+ Annotation annotation = (Annotation) expressionStack[expressionPtr];
+ this.patternLocator.match(annotation, nodeSet);
+}
+protected void consumeMemberValuePair() {
+ super.consumeMemberValuePair();
+
+ // this is always a MemberValuePair
+ this.patternLocator.match((MemberValuePair) this.astStack[this.astPtr], this.nodeSet);
+}
protected void consumeMethodInvocationName() {
super.consumeMethodInvocationName();
@@ -268,6 +259,12 @@
// this is always a MessageSend
this.patternLocator.match((MessageSend) this.expressionStack[this.expressionPtr], this.nodeSet);
}
+protected void consumeNormalAnnotation() {
+ super.consumeNormalAnnotation();
+ // this is always an Annotation
+ Annotation annotation = (Annotation) expressionStack[expressionPtr];
+ this.patternLocator.match(annotation, nodeSet);
+}
protected void consumePrimaryNoNewArray() {
// pop parenthesis positions (and don't update expression positions
// (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=23329)
@@ -283,6 +280,12 @@
intPtr--;
intPtr--;
}
+protected void consumeSingleMemberAnnotation() {
+ super.consumeSingleMemberAnnotation();
+ // this is always an Annotation
+ Annotation annotation = (Annotation) expressionStack[expressionPtr];
+ this.patternLocator.match(annotation, nodeSet);
+}
protected void consumeTypeArgument() {
super.consumeTypeArgument();
patternLocator.match((TypeReference)genericsStack[genericsPtr], nodeSet);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java
index fd4da6e..796efc9 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java
@@ -36,12 +36,23 @@
static Integer ERASURE_MATCH = new Integer(SearchPattern.R_ERASURE_MATCH);
/**
+ * Tell whether locators need to resolve or not for current matching node set.
+ */
+public boolean mustResolve;
+
+/**
* Set of possible matching ast nodes. They need to be resolved
* to determine if they really match the search pattern.
*/
SimpleSet possibleMatchingNodesSet = new SimpleSet(7);
private HashtableOfLong possibleMatchingNodesKeys = new HashtableOfLong(7);
+
+public MatchingNodeSet(boolean mustResolvePattern) {
+ super();
+ mustResolve = mustResolvePattern;
+}
+
public int addMatch(ASTNode node, int matchLevel) {
switch (matchLevel) {
case PatternLocator.INACCURATE_MATCH:
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
index 2fc4632..437d78e 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
@@ -10,12 +10,13 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core.search.matching;
+import java.util.HashMap;
+
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.search.*;
-import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.lookup.*;
@@ -30,12 +31,21 @@
//extra reference info
public char[][][] allSuperDeclaringTypeNames;
+//method declarations which parameters verification fail
+private HashMap methodDeclarationsWithInvalidParam = new HashMap();
+
public MethodLocator(MethodPattern pattern) {
super(pattern);
this.pattern = pattern;
this.isDeclarationOfReferencedMethodsPattern = this.pattern instanceof DeclarationOfReferencedMethodsPattern;
}
+/*
+ * Clear caches
+ */
+protected void clear() {
+ this.methodDeclarationsWithInvalidParam = new HashMap();
+}
public void initializePolymorphicSearch(MatchLocator locator) {
try {
this.allSuperDeclaringTypeNames =
@@ -50,6 +60,19 @@
// inaccurate matches will be found
}
}
+/*
+ * Return whether a type name is in pattern all super declaring types names.
+ */
+boolean isTypeInSuperDeclaringTypeNames(char[][] typeName) {
+ if (allSuperDeclaringTypeNames == null) return false;
+ int length = allSuperDeclaringTypeNames.length;
+ for (int i= 0; i<length; i++) {
+ if (CharOperation.equals(allSuperDeclaringTypeNames[i], typeName)) {
+ return true;
+ }
+ }
+ return false;
+}
/**
* Returns whether the code gen will use an invoke virtual for
* this message send or not.
@@ -86,13 +109,27 @@
if (!matchesName(this.pattern.selector, node.selector)) return IMPOSSIBLE_MATCH;
// Verify parameters types
+ boolean resolve = ((InternalSearchPattern)this.pattern).mustResolve;
if (this.pattern.parameterSimpleNames != null) {
int length = this.pattern.parameterSimpleNames.length;
ASTNode[] args = node.arguments;
int argsLength = args == null ? 0 : args.length;
if (length != argsLength) return IMPOSSIBLE_MATCH;
for (int i = 0; i < argsLength; i++) {
- if (!matchesTypeReference(this.pattern.parameterSimpleNames[i], ((Argument) args[i]).type)) return IMPOSSIBLE_MATCH;
+ if (!matchesTypeReference(this.pattern.parameterSimpleNames[i], ((Argument) args[i]).type)) {
+ // Do not return as impossible when source level is at least 1.5
+ if (this.mayBeGeneric) {
+ if (!((InternalSearchPattern)this.pattern).mustResolve) {
+ // Set resolution flag on node set in case of types was inferred in parameterized types from generic ones...
+ // (see bugs https://bugs.eclipse.org/bugs/show_bug.cgi?id=79990, 96761, 96763)
+ nodeSet.mustResolve = true;
+ resolve = true;
+ }
+ this.methodDeclarationsWithInvalidParam.put(node, null);
+ } else {
+ return IMPOSSIBLE_MATCH;
+ }
+ }
}
}
@@ -102,6 +139,13 @@
}
// Method declaration may match pattern
+ return nodeSet.addMatch(node, resolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+}
+public int match(MemberValuePair node, MatchingNodeSet nodeSet) {
+ if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
+
+ if (!matchesName(this.pattern.selector, node.name)) return IMPOSSIBLE_MATCH;
+
return nodeSet.addMatch(node, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
}
public int match(MessageSend node, MatchingNodeSet nodeSet) {
@@ -118,6 +162,22 @@
return nodeSet.addMatch(node, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
}
//public int match(Reference node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(Annotation node, MatchingNodeSet nodeSet) {
+ if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
+ MemberValuePair[] pairs = node.memberValuePairs();
+ if (pairs == null || pairs.length == 0) return IMPOSSIBLE_MATCH;
+
+ int length = pairs.length;
+ MemberValuePair pair = null;
+ for (int i=0; i<length; i++) {
+ pair = node.memberValuePairs()[i];
+ if (matchesName(this.pattern.selector, pair.name)) {
+ ASTNode possibleNode = (node instanceof SingleMemberAnnotation) ? (ASTNode) node : pair;
+ return nodeSet.addMatch(possibleNode, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+ }
+ }
+ return IMPOSSIBLE_MATCH;
+}
//public int match(TypeDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
//public int match(TypeReference node, MatchingNodeSet nodeSet) - SKIP IT
@@ -137,7 +197,7 @@
super.matchLevelAndReportImportRef(importRef, binding, locator);
}
}
-protected int matchMethod(MethodBinding method) {
+protected int matchMethod(MethodBinding method, boolean skipImpossibleArg) {
if (!matchesName(this.pattern.selector, method.selector)) return IMPOSSIBLE_MATCH;
int level = ACCURATE_MATCH;
@@ -179,10 +239,13 @@
}
if (level > newLevel) {
if (newLevel == IMPOSSIBLE_MATCH) {
-// if (isErasureMatch) {
-// return ERASURE_MATCH;
-// }
- return IMPOSSIBLE_MATCH;
+ if (skipImpossibleArg) {
+ // Do not consider match as impossible while finding declarations and source level >= 1.5
+ // (see bugs https://bugs.eclipse.org/bugs/show_bug.cgi?id=79990, 96761, 96763)
+ newLevel = level;
+ } else {
+ return IMPOSSIBLE_MATCH;
+ }
}
level = newLevel; // can only be downgraded
}
@@ -191,11 +254,61 @@
return level;
}
+private boolean matchOverriddenMethod(ReferenceBinding type, MethodBinding method, MethodBinding matchMethod) {
+ if (type == null) return false;
+
+ // matches superclass
+ if (!type.isInterface() && !CharOperation.equals(type.compoundName, TypeConstants.JAVA_LANG_OBJECT)) {
+ ReferenceBinding superClass = type.superclass();
+ if (superClass.isParameterizedType()) {
+ MethodBinding[] methods = superClass.getMethods(this.pattern.selector);
+ int length = methods.length;
+ for (int i = 0; i<length; i++) {
+ if (methods[i].areParametersEqual(method)) {
+ if (matchMethod == null) {
+ if (methodParametersEqualsPattern(methods[i].original())) return true;
+ } else {
+ if (methodsHaveSameParameters(methods[i].original(), matchMethod)) return true;
+ }
+ }
+ }
+ }
+ if (matchOverriddenMethod(superClass, method, matchMethod)) {
+ return true;
+ }
+ }
+
+ // matches interfaces
+ ReferenceBinding[] interfaces = type.superInterfaces();
+ if (interfaces == null) return false;
+ int iLength = interfaces.length;
+ for (int i = 0; i<iLength; i++) {
+ if (interfaces[i].isParameterizedType()) {
+ MethodBinding[] methods = interfaces[i].getMethods(this.pattern.selector);
+ int length = methods.length;
+ for (int j = 0; j<length; j++) {
+ if (methods[j].areParametersEqual(method)) {
+ if (matchMethod == null) {
+ if (methodParametersEqualsPattern(methods[j].original())) return true;
+ } else {
+ if (methodsHaveSameParameters(methods[j].original(), matchMethod)) return true;
+ }
+ }
+ }
+ }
+ if (matchOverriddenMethod(interfaces[i], method, matchMethod)) {
+ return true;
+ }
+ }
+ return false;
+}
/**
* @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchReportReference(org.eclipse.jdt.internal.compiler.ast.ASTNode, org.eclipse.jdt.core.IJavaElement, Binding, int, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
*/
protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+ MethodBinding methodBinding = (reference instanceof MessageSend) ? ((MessageSend)reference).binding: ((elementBinding instanceof MethodBinding) ? (MethodBinding) elementBinding : null);
if (this.isDeclarationOfReferencedMethodsPattern) {
+ if (methodBinding == null) return;
// need exact match to be able to open on type ref
if (accuracy != SearchMatch.A_ACCURATE) return;
@@ -204,7 +317,7 @@
while (element != null && !declPattern.enclosingElement.equals(element))
element = element.getParent();
if (element != null) {
- reportDeclaration(((MessageSend) reference).binding, locator, declPattern.knownMethods);
+ reportDeclaration(methodBinding, locator, declPattern.knownMethods);
}
} else {
match = locator.newMethodReferenceMatch(element, elementBinding, accuracy, -1, -1, false /*not constructor*/, false/*not synthetic*/, reference);
@@ -213,17 +326,23 @@
// verify closest match if pattern was bound
// (see bug 70827)
if (focus != null && focus.getElementType() == IJavaElement.METHOD) {
- MethodBinding method = ((MessageSend)reference).binding;
- boolean isPrivate = Flags.isPrivate(((IMethod) focus).getFlags());
- if (isPrivate && !CharOperation.equals(method.declaringClass.sourceName, focus.getParent().getElementName().toCharArray())) {
- return; // finally the match was not possible
+ if (methodBinding != null) {
+ boolean isPrivate = Flags.isPrivate(((IMethod) focus).getFlags());
+ if (isPrivate && !CharOperation.equals(methodBinding.declaringClass.sourceName, focus.getParent().getElementName().toCharArray())) {
+ return; // finally the match was not possible
+ }
}
}
matchReportReference((MessageSend)reference, locator, ((MessageSend)reference).binding);
} else {
+ if (reference instanceof SingleMemberAnnotation) {
+ reference = ((SingleMemberAnnotation)reference).memberValuePairs()[0];
+ match.setImplicit(true);
+ }
int offset = reference.sourceStart;
+ int length = reference.sourceEnd - offset + 1;
match.setOffset(offset);
- match.setLength(reference.sourceEnd-offset+1);
+ match.setLength(length);
locator.report(match);
}
}
@@ -302,6 +421,71 @@
locator.report(match);
}
}
+/*
+ * Return whether method parameters are equals to pattern ones.
+ */
+private boolean methodParametersEqualsPattern(MethodBinding method) {
+ TypeBinding[] methodParameters = method.parameters;
+
+ int length = methodParameters==null ? 0 : methodParameters.length;
+ int patternLength = this.pattern.parameterSimpleNames==null ? 0 : this.pattern.parameterSimpleNames.length;
+ if (length != patternLength) return false;
+
+ for (int i = 0; i < length; i++) {
+ char[] paramQualifiedName = qualifiedPattern(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i]);
+ if (!CharOperation.match(paramQualifiedName, methodParameters[i].readableName(), this.isCaseSensitive)) {
+ return false;
+ }
+ }
+ return true;
+}
+private boolean methodsHaveSameParameters(MethodBinding method, MethodBinding matchMethod) {
+ TypeBinding[] methodParameters = method.parameters;
+ TypeBinding[] matchMethodParameters = matchMethod.parameters;
+
+ int length = methodParameters==null ? 0 : methodParameters.length;
+ int matchLength = matchMethodParameters==null ? 0 : matchMethodParameters.length;
+ if (length != matchLength) return false;
+
+ for (int i = 0; i < length; i++) {
+ if (!CharOperation.equals(methodParameters[i].readableName(), matchMethodParameters[i].readableName(), this.isCaseSensitive)) {
+ return false;
+ }
+ }
+ return true;
+}
+public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) {
+ if (elementBinding != null) {
+ MethodBinding methodBinding = (MethodBinding) elementBinding;
+ // If method parameters verification was not valid, then try to see if method arguments can match a method in hierarchy
+ if (this.methodDeclarationsWithInvalidParam.containsKey(reference)) {
+ // First see if this reference has already been resolved => report match if validated
+ Boolean report = (Boolean) this.methodDeclarationsWithInvalidParam.get(reference);
+ if (report != null) {
+ if (report.booleanValue()) {
+ return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
+ }
+ return null;
+ }
+ // If method binding override a method in super hierarchy which original match pattern then report match
+ if (matchOverriddenMethod(methodBinding.declaringClass, methodBinding, null)) {
+ this.methodDeclarationsWithInvalidParam.put(reference, Boolean.TRUE);
+ return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
+ }
+ // If pattern binding override a method in super hierarchy which original match method binding then report match
+ MethodBinding patternBinding = locator.getMethodBinding(this.pattern);
+ if (patternBinding != null) {
+ if (matchOverriddenMethod(patternBinding.declaringClass, patternBinding, methodBinding)) {
+ this.methodDeclarationsWithInvalidParam.put(reference, Boolean.TRUE);
+ return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
+ }
+ }
+ this.methodDeclarationsWithInvalidParam.put(reference, Boolean.FALSE);
+ return null;
+ }
+ }
+ return super.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
+}
protected int referenceType() {
return IJavaElement.METHOD;
}
@@ -311,11 +495,16 @@
if (type == null) return; // case of a secondary type
char[] bindingSelector = methodBinding.selector;
- TypeBinding[] parameters = methodBinding.parameters;
+ TypeBinding[] parameters = methodBinding.original().parameters;
int parameterLength = parameters.length;
String[] parameterTypes = new String[parameterLength];
- for (int i = 0; i < parameterLength; i++)
- parameterTypes[i] = Signature.createTypeSignature(parameters[i].sourceName(), false);
+ for (int i = 0; i < parameterLength; i++) {
+ char[] typeName = parameters[i].shortReadableName();
+ if (parameters[i].isMemberType()) {
+ typeName = CharOperation.subarray(typeName, CharOperation.indexOf('.', typeName)+1, typeName.length);
+ }
+ parameterTypes[i] = Signature.createTypeSignature(typeName, false);
+ }
IMethod method = type.getMethod(new String(bindingSelector), parameterTypes);
if (knownMethods.includes(method)) return;
@@ -354,10 +543,24 @@
}
}
public int resolveLevel(ASTNode possibleMatchingNode) {
- if (this.pattern.findReferences && possibleMatchingNode instanceof MessageSend)
- return resolveLevel((MessageSend) possibleMatchingNode);
- if (this.pattern.findDeclarations && possibleMatchingNode instanceof MethodDeclaration)
- return resolveLevel(((MethodDeclaration) possibleMatchingNode).binding);
+ if (this.pattern.findReferences) {
+ if (possibleMatchingNode instanceof MessageSend) {
+ return resolveLevel((MessageSend) possibleMatchingNode);
+ }
+ if (possibleMatchingNode instanceof SingleMemberAnnotation) {
+ SingleMemberAnnotation annotation = (SingleMemberAnnotation) possibleMatchingNode;
+ return resolveLevel(annotation.memberValuePairs()[0].binding);
+ }
+ if (possibleMatchingNode instanceof MemberValuePair) {
+ MemberValuePair memberValuePair = (MemberValuePair) possibleMatchingNode;
+ return resolveLevel(memberValuePair.binding);
+ }
+ }
+ if (this.pattern.findDeclarations) {
+ if (possibleMatchingNode instanceof MethodDeclaration) {
+ return resolveLevel(((MethodDeclaration) possibleMatchingNode).binding);
+ }
+ }
return IMPOSSIBLE_MATCH;
}
public int resolveLevel(Binding binding) {
@@ -365,11 +568,15 @@
if (!(binding instanceof MethodBinding)) return IMPOSSIBLE_MATCH;
MethodBinding method = (MethodBinding) binding;
- int methodLevel = matchMethod(method);
+ boolean skipVerif = this.pattern.findDeclarations && this.mayBeGeneric;
+ int methodLevel = matchMethod(method, skipVerif);
if (methodLevel == IMPOSSIBLE_MATCH) {
- if (method != method.original()) methodLevel = matchMethod(method.original());
- if (methodLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
- method = method.original();
+ if (method != method.original()) methodLevel = matchMethod(method.original(), skipVerif);
+ if (methodLevel == IMPOSSIBLE_MATCH) {
+ return IMPOSSIBLE_MATCH;
+ } else {
+ method = method.original();
+ }
}
// declaring type
@@ -387,11 +594,21 @@
}
protected int resolveLevel(MessageSend messageSend) {
MethodBinding method = messageSend.binding;
- if (method == null || messageSend.resolvedType == null) return INACCURATE_MATCH;
+ if (method == null) return INACCURATE_MATCH;
+ if (messageSend.resolvedType == null) {
+ // Closest match may have different argument numbers when ProblemReason is NotFound
+ // see MessageSend#resolveType(BlockScope)
+ // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=97322
+ int argLength = messageSend.arguments == null ? 0 : messageSend.arguments.length;
+ if (pattern.parameterSimpleNames == null || argLength == pattern.parameterSimpleNames.length) {
+ return INACCURATE_MATCH;
+ }
+ return IMPOSSIBLE_MATCH;
+ }
- int methodLevel = matchMethod(method);
+ int methodLevel = matchMethod(method, false);
if (methodLevel == IMPOSSIBLE_MATCH) {
- if (method != method.original()) methodLevel = matchMethod(method.original());
+ if (method != method.original()) methodLevel = matchMethod(method.original(), false);
if (methodLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
method = method.original();
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java
index 14497dc..83a8828 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java
@@ -143,9 +143,9 @@
// Get unique key for parameterized constructors
String genericDeclaringTypeSignature = null;
// String genericSignature = null;
- BindingKey key;
- if (method.isResolved() && (key = new BindingKey(method.getKey())).isParameterizedType()) {
- genericDeclaringTypeSignature = key.getDeclaringTypeSignature();
+ String key;
+ if (method.isResolved() && (new BindingKey(key = method.getKey())).isParameterizedType()) {
+ genericDeclaringTypeSignature = Util.getDeclaringTypeSignature(key);
} else {
methodParameters = true;
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MultiTypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MultiTypeDeclarationPattern.java
index 8573e4c..545e07a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MultiTypeDeclarationPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MultiTypeDeclarationPattern.java
@@ -59,7 +59,7 @@
}
this.typeSuffix = typeSuffix;
- ((InternalSearchPattern)this).mustResolve = false; // only used to report type declarations, not their positions
+ ((InternalSearchPattern)this).mustResolve = typeSuffix != TYPE_SUFFIX; // only used to report type declarations, not their positions
}
MultiTypeDeclarationPattern(int matchRule) {
super(TYPE_DECL_PATTERN, matchRule);
@@ -74,10 +74,56 @@
QualifiedTypeDeclarationPattern pattern = (QualifiedTypeDeclarationPattern) decodedPattern;
switch(this.typeSuffix) {
case CLASS_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case CLASS_SUFFIX :
+ case CLASS_AND_INTERFACE_SUFFIX :
+ case CLASS_AND_ENUM_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
case INTERFACE_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case INTERFACE_SUFFIX :
+ case CLASS_AND_INTERFACE_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
case ENUM_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case ENUM_SUFFIX :
+ case CLASS_AND_ENUM_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
case ANNOTATION_TYPE_SUFFIX :
if (this.typeSuffix != pattern.typeSuffix) return false;
+ break;
+ case CLASS_AND_INTERFACE_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case CLASS_SUFFIX :
+ case INTERFACE_SUFFIX :
+ case CLASS_AND_INTERFACE_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
+ case CLASS_AND_ENUM_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case CLASS_SUFFIX :
+ case ENUM_SUFFIX :
+ case CLASS_AND_ENUM_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
}
if (this.qualifications != null) {
@@ -143,6 +189,12 @@
case CLASS_SUFFIX :
output.append("MultiClassDeclarationPattern: "); //$NON-NLS-1$
break;
+ case CLASS_AND_INTERFACE_SUFFIX :
+ output.append("MultiClassAndInterfaceDeclarationPattern: "); //$NON-NLS-1$
+ break;
+ case CLASS_AND_ENUM_SUFFIX :
+ output.append("MultiClassAndEnumDeclarationPattern: "); //$NON-NLS-1$
+ break;
case INTERFACE_SUFFIX :
output.append("MultiInterfaceDeclarationPattern: "); //$NON-NLS-1$
break;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
index db30052..3fecf99 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
@@ -12,9 +12,23 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.search.*;
-import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ImportReference;
+import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Reference;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
public class OrLocator extends PatternLocator {
@@ -150,19 +164,40 @@
return result;
}
protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException {
+
+ // for static import, binding can be a field binding or a member type binding
+ // verify that in this case binding is static and use declaring class for fields
+ Binding refBinding = binding;
+ if (importRef.isStatic()) {
+ if (binding instanceof FieldBinding) {
+ FieldBinding fieldBinding = (FieldBinding) binding;
+ if (!fieldBinding.isStatic()) return;
+ refBinding = fieldBinding.declaringClass;
+ } else if (binding instanceof MethodBinding) {
+ MethodBinding methodBinding = (MethodBinding) binding;
+ if (!methodBinding.isStatic()) return;
+ refBinding = methodBinding.declaringClass;
+ } else if (binding instanceof MemberTypeBinding) {
+ MemberTypeBinding memberBinding = (MemberTypeBinding) binding;
+ if (!memberBinding.isStatic()) return;
+ }
+ }
+
+ // Look for closest pattern
PatternLocator closestPattern = null;
int level = IMPOSSIBLE_MATCH;
for (int i = 0, length = this.patternLocators.length; i < length; i++) {
PatternLocator patternLocator = this.patternLocators[i];
- int newLevel = patternLocator.referenceType() == 0 ? IMPOSSIBLE_MATCH : patternLocator.resolveLevel(binding);
+ int newLevel = patternLocator.referenceType() == 0 ? IMPOSSIBLE_MATCH : patternLocator.resolveLevel(refBinding);
if (newLevel > level) {
closestPattern = patternLocator;
if (newLevel == ACCURATE_MATCH) break;
level = newLevel;
}
}
- if (closestPattern != null)
+ if (closestPattern != null) {
closestPattern.matchLevelAndReportImportRef(importRef, binding, locator);
+ }
}
protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
PatternLocator closestPattern = null;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java
index 8d5ef8a..f1a58f2 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java
@@ -90,13 +90,7 @@
}
protected int matchLevel(ImportReference importRef) {
- // Compare prefix also for static import
- if (!importRef.onDemand || importRef.isStatic())
- return matchLevelForTokens(importRef.tokens);
-
- return matchesName(this.pattern.pkgName, CharOperation.concatWith(importRef.tokens, '.'))
- ? ACCURATE_MATCH
- : IMPOSSIBLE_MATCH;
+ return matchLevelForTokens(importRef.tokens);
}
protected int matchLevelForTokens(char[][] tokens) {
if (this.pattern.pkgName == null) return ACCURATE_MATCH;
@@ -148,7 +142,7 @@
long[] positions = importRef.sourcePositions;
int last = positions.length - 1;
if (binding instanceof ProblemReferenceBinding)
- binding = ((ProblemReferenceBinding) binding).original;
+ binding = ((ProblemReferenceBinding) binding).closestMatch;
if (binding instanceof ReferenceBinding) {
PackageBinding pkgBinding = ((ReferenceBinding) binding).fPackage;
if (pkgBinding != null)
@@ -211,12 +205,23 @@
if (typeBinding instanceof ArrayBinding)
typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
if (typeBinding instanceof ProblemReferenceBinding)
- typeBinding = ((ProblemReferenceBinding) typeBinding).original;
+ typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch;
if (typeBinding instanceof ReferenceBinding) {
PackageBinding pkgBinding = ((ReferenceBinding) typeBinding).fPackage;
if (pkgBinding != null)
last = pkgBinding.compoundName.length;
}
+ // Do not report qualified references which are only enclosing type
+ // (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=91078)
+ ReferenceBinding enclosingType = typeBinding == null ? null: typeBinding.enclosingType();
+ if (enclosingType != null) {
+ int length = positions.length;
+ while (enclosingType != null && length > 0) {
+ length--;
+ enclosingType = enclosingType.enclosingType();
+ }
+ if (length <= 1) return;
+ }
}
if (last == -1) {
last = this.pattern.segments.length;
@@ -263,7 +268,7 @@
if (binding instanceof ArrayBinding)
binding = ((ArrayBinding) binding).leafComponentType;
if (binding instanceof ProblemReferenceBinding)
- binding = ((ProblemReferenceBinding) binding).original;
+ binding = ((ProblemReferenceBinding) binding).closestMatch;
if (binding == null) return INACCURATE_MATCH;
if (binding instanceof ReferenceBinding) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
index 0513a84..c41fc42 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
@@ -26,6 +26,7 @@
protected boolean isEquivalentMatch;
protected boolean isErasureMatch;
protected boolean mustResolve;
+protected boolean mayBeGeneric;
// match to report
SearchMatch match = null;
@@ -106,6 +107,12 @@
this.matchMode = matchRule & JavaSearchPattern.MATCH_MODE_MASK;
this.mustResolve = ((InternalSearchPattern)pattern).mustResolve;
}
+/*
+ * Clear caches
+ */
+protected void clear() {
+ // nothing to clear by default
+}
/* (non-Javadoc)
* Modify PatternLocator.qualifiedPattern behavior:
* do not add star before simple name pattern when qualification pattern is null.
@@ -151,6 +158,10 @@
public void initializePolymorphicSearch(MatchLocator locator) {
// default is to do nothing
}
+public int match(Annotation node, MatchingNodeSet nodeSet) {
+ // each subtype should override if needed
+ return IMPOSSIBLE_MATCH;
+}
/**
* Check if the given ast node syntactically matches this pattern.
* If it does, add it to the match set.
@@ -180,6 +191,10 @@
// each subtype should override if needed
return IMPOSSIBLE_MATCH;
}
+public int match(MemberValuePair node, MatchingNodeSet nodeSet) {
+ // each subtype should override if needed
+ return IMPOSSIBLE_MATCH;
+}
public int match(MessageSend node, MatchingNodeSet nodeSet) {
// each subtype should override if needed
return IMPOSSIBLE_MATCH;
@@ -642,7 +657,6 @@
int impossible = this.isErasureMatch ? ERASURE_MATCH : IMPOSSIBLE_MATCH;
// pattern has type parameter(s) or type argument(s)
- boolean isRawType = type.isRawType();
if (type.isGenericType()) {
// Binding is generic, get its type variable(s)
TypeVariableBinding[] typeVariables = null;
@@ -660,14 +674,16 @@
}
// TODO (frederic) do we need to verify each parameter?
return level; // we can't do better
- } else if (isRawType) {
+ } else if (type.isRawType()) {
return level; // raw type always match
- } else if (!type.isParameterizedType()) {
- // Standard types (ie. neither generic nor parameterized nor raw types)
- // cannot match pattern with type parameters or arguments
- return (patternTypeArguments[depth]==null || patternTypeArguments[depth].length==0) ? level : IMPOSSIBLE_MATCH;
} else {
- ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) type;
+ TypeBinding leafType = type.leafComponentType();
+ if (!leafType.isParameterizedType()) {
+ // Standard types (ie. neither generic nor parameterized nor raw types)
+ // cannot match pattern with type parameters or arguments
+ return (patternTypeArguments[depth]==null || patternTypeArguments[depth].length==0) ? level : IMPOSSIBLE_MATCH;
+ }
+ ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) leafType;
// Compare arguments only if there ones on both sides
if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 &&
@@ -756,31 +772,21 @@
// If pattern is not exact then match fails
if (patternTypeArgHasAnyChars) return impossible;
- // Get reference binding
- ReferenceBinding refBinding = null;
- if (argTypeBinding.isArrayType()) {
- TypeBinding leafBinding = ((ArrayBinding) argTypeBinding).leafComponentType;
- if (!leafBinding.isBaseType()) {
- refBinding = (ReferenceBinding) leafBinding;
- }
- } else if (!argTypeBinding.isBaseType()) {
- refBinding = (ReferenceBinding) argTypeBinding;
- }
// Scan hierarchy
- if (refBinding != null) {
- refBinding = refBinding.superclass();
- while (refBinding != null) {
- if (CharOperation.equals(patternTypeArgument, refBinding.shortReadableName(), this.isCaseSensitive) ||
- CharOperation.equals(patternTypeArgument, refBinding.readableName(), this.isCaseSensitive)) {
- // found name in hierarchy => match
+ TypeBinding leafTypeBinding = argTypeBinding.leafComponentType();
+ if (leafTypeBinding.isBaseType()) return impossible;
+ ReferenceBinding refBinding = ((ReferenceBinding) leafTypeBinding).superclass();
+ while (refBinding != null) {
+ if (CharOperation.equals(patternTypeArgument, refBinding.shortReadableName(), this.isCaseSensitive) ||
+ CharOperation.equals(patternTypeArgument, refBinding.readableName(), this.isCaseSensitive)) {
+ // found name in hierarchy => match
+ continue nextTypeArgument;
+ } else if (refBinding.isLocalType() || refBinding.isMemberType()) {
+ // for local or member type, verify also source name (bug 81084)
+ if (CharOperation.match(patternTypeArgument, refBinding.sourceName(), this.isCaseSensitive))
continue nextTypeArgument;
- } else if (refBinding.isLocalType() || refBinding.isMemberType()) {
- // for local or member type, verify also source name (bug 81084)
- if (CharOperation.match(patternTypeArgument, refBinding.sourceName(), this.isCaseSensitive))
- continue nextTypeArgument;
- }
- refBinding = refBinding.superclass();
}
+ refBinding = refBinding.superclass();
}
return impossible;
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
index 1b2021e..e9694d6 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
@@ -33,11 +33,11 @@
private String sourceFileName;
private char[] source;
-public PossibleMatch(MatchLocator locator, IResource resource, Openable openable, SearchDocument document) {
+public PossibleMatch(MatchLocator locator, IResource resource, Openable openable, SearchDocument document, boolean mustResolve) {
this.resource = resource;
this.openable = openable;
this.document = document;
- this.nodeSet = new MatchingNodeSet();
+ this.nodeSet = new MatchingNodeSet(mustResolve);
char[] qualifiedName = getQualifiedName();
if (qualifiedName != null)
this.compoundName = CharOperation.splitOn('.', qualifiedName);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java
index 1c0d908..8c5aeca 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java
@@ -26,7 +26,7 @@
this.simpleName = isCaseSensitive() ? simpleName : CharOperation.toLowerCase(simpleName);
this.typeSuffix = typeSuffix;
- ((InternalSearchPattern)this).mustResolve = this.qualification != null;
+ ((InternalSearchPattern)this).mustResolve = this.qualification != null || typeSuffix != TYPE_SUFFIX;
}
QualifiedTypeDeclarationPattern(int matchRule) {
super(matchRule);
@@ -60,7 +60,7 @@
public char[] getPackageName() {
if (this.packageIndex == -1)
return this.qualification;
- return CharOperation.subarray(this.qualification, 0, this.packageIndex);
+ return internedPackageNames.add(CharOperation.subarray(this.qualification, 0, this.packageIndex));
}
public char[][] getEnclosingTypeNames() {
if (this.packageIndex == -1)
@@ -75,10 +75,56 @@
QualifiedTypeDeclarationPattern pattern = (QualifiedTypeDeclarationPattern) decodedPattern;
switch(this.typeSuffix) {
case CLASS_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case CLASS_SUFFIX :
+ case CLASS_AND_INTERFACE_SUFFIX :
+ case CLASS_AND_ENUM_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
case INTERFACE_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case INTERFACE_SUFFIX :
+ case CLASS_AND_INTERFACE_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
case ENUM_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case ENUM_SUFFIX :
+ case CLASS_AND_ENUM_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
case ANNOTATION_TYPE_SUFFIX :
if (this.typeSuffix != pattern.typeSuffix) return false;
+ break;
+ case CLASS_AND_INTERFACE_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case CLASS_SUFFIX :
+ case INTERFACE_SUFFIX :
+ case CLASS_AND_INTERFACE_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
+ case CLASS_AND_ENUM_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case CLASS_SUFFIX :
+ case ENUM_SUFFIX :
+ case CLASS_AND_ENUM_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
}
return matchesName(this.simpleName, pattern.simpleName) && matchesName(this.qualification, pattern.qualification);
@@ -88,6 +134,12 @@
case CLASS_SUFFIX :
output.append("ClassDeclarationPattern: qualification<"); //$NON-NLS-1$
break;
+ case CLASS_AND_INTERFACE_SUFFIX:
+ output.append("ClassAndInterfaceDeclarationPattern: qualification<"); //$NON-NLS-1$
+ break;
+ case CLASS_AND_ENUM_SUFFIX :
+ output.append("ClassAndEnumDeclarationPattern: qualification<"); //$NON-NLS-1$
+ break;
case INTERFACE_SUFFIX :
output.append("InterfaceDeclarationPattern: qualification<"); //$NON-NLS-1$
break;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java
index 1a52791..a50bcf1 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java
@@ -52,10 +52,22 @@
switch (this.pattern.typeSuffix) {
case CLASS_SUFFIX:
- if (type.isInterface()) return IMPOSSIBLE_MATCH;
+ if (!type.isClass()) return IMPOSSIBLE_MATCH;
+ break;
+ case CLASS_AND_INTERFACE_SUFFIX:
+ if (!(type.isClass() || (type.isInterface() && !type.isAnnotationType()))) return IMPOSSIBLE_MATCH;
+ break;
+ case CLASS_AND_ENUM_SUFFIX:
+ if (!(type.isClass() || type.isEnum())) return IMPOSSIBLE_MATCH;
break;
case INTERFACE_SUFFIX:
- if (!type.isInterface()) return IMPOSSIBLE_MATCH;
+ if (!type.isInterface() || type.isAnnotationType()) return IMPOSSIBLE_MATCH;
+ break;
+ case ENUM_SUFFIX:
+ if (!type.isEnum()) return IMPOSSIBLE_MATCH;
+ break;
+ case ANNOTATION_TYPE_SUFFIX:
+ if (!type.isAnnotationType()) return IMPOSSIBLE_MATCH;
break;
case TYPE_SUFFIX : // nothing
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java
index 0ceee8a..8e9aa24 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java
@@ -34,6 +34,51 @@
protected static char[][] CATEGORIES = { TYPE_DECL };
+// want to save space by interning the package names for each match
+static PackageNameSet internedPackageNames = new PackageNameSet(1001);
+static class PackageNameSet {
+
+public char[][] names;
+public int elementSize; // number of elements in the table
+public int threshold;
+
+PackageNameSet(int size) {
+ this.elementSize = 0;
+ this.threshold = size; // size represents the expected number of elements
+ int extraRoom = (int) (size * 1.5f);
+ if (this.threshold == extraRoom)
+ extraRoom++;
+ this.names = new char[extraRoom][];
+}
+
+char[] add(char[] name) {
+ int length = names.length;
+ int index = CharOperation.hashCode(name) % length;
+ char[] current;
+ while ((current = names[index]) != null) {
+ if (CharOperation.equals(current, name)) return current;
+ if (++index == length) index = 0;
+ }
+ names[index] = name;
+
+ // assumes the threshold is never equal to the size of the table
+ if (++elementSize > threshold) rehash();
+ return name;
+}
+
+void rehash() {
+ PackageNameSet newSet = new PackageNameSet(elementSize * 2); // double the number of expected elements
+ char[] current;
+ for (int i = names.length; --i >= 0;)
+ if ((current = names[i]) != null)
+ newSet.add(current);
+
+ this.names = newSet.names;
+ this.elementSize = newSet.elementSize;
+ this.threshold = newSet.threshold;
+}
+}
+
/*
* Create index key for type declaration pattern:
* key = typeName / packageName / enclosingTypeName / typeSuffix modifiers
@@ -98,7 +143,7 @@
this.simpleName = isCaseSensitive() ? simpleName : CharOperation.toLowerCase(simpleName);
this.typeSuffix = typeSuffix;
- ((InternalSearchPattern)this).mustResolve = this.pkg != null && this.enclosingTypeNames != null;
+ ((InternalSearchPattern)this).mustResolve = (this.pkg != null && this.enclosingTypeNames != null) || typeSuffix != TYPE_SUFFIX;
}
TypeDeclarationPattern(int matchRule) {
super(TYPE_DECL_PATTERN, matchRule);
@@ -115,7 +160,7 @@
int start = slash + 1;
slash = CharOperation.indexOf(SEPARATOR, key, start);
- this.pkg = slash == start ? CharOperation.NO_CHAR : CharOperation.subarray(key, start, slash);
+ this.pkg = slash == start ? CharOperation.NO_CHAR : internedPackageNames.add(CharOperation.subarray(key, start, slash));
slash = CharOperation.indexOf(SEPARATOR, key, start = slash + 1);
if (slash == start) {
@@ -158,10 +203,56 @@
TypeDeclarationPattern pattern = (TypeDeclarationPattern) decodedPattern;
switch(this.typeSuffix) {
case CLASS_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case CLASS_SUFFIX :
+ case CLASS_AND_INTERFACE_SUFFIX :
+ case CLASS_AND_ENUM_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
case INTERFACE_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case INTERFACE_SUFFIX :
+ case CLASS_AND_INTERFACE_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
case ENUM_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case ENUM_SUFFIX :
+ case CLASS_AND_ENUM_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
case ANNOTATION_TYPE_SUFFIX :
if (this.typeSuffix != pattern.typeSuffix) return false;
+ break;
+ case CLASS_AND_INTERFACE_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case CLASS_SUFFIX :
+ case INTERFACE_SUFFIX :
+ case CLASS_AND_INTERFACE_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
+ case CLASS_AND_ENUM_SUFFIX :
+ switch (pattern.typeSuffix) {
+ case CLASS_SUFFIX :
+ case ENUM_SUFFIX :
+ case CLASS_AND_ENUM_SUFFIX :
+ break;
+ default:
+ return false;
+ }
+ break;
}
if (!matchesName(this.simpleName, pattern.simpleName))
@@ -209,8 +300,9 @@
case INTERFACE_SUFFIX :
case ENUM_SUFFIX :
case ANNOTATION_TYPE_SUFFIX :
- key = new char[] {ONE_STAR[0], SEPARATOR,
- isCaseSensitive() ? this.typeSuffix : Character.toLowerCase(this.typeSuffix)}; // find all classes or all interfaces
+ case CLASS_AND_INTERFACE_SUFFIX :
+ case CLASS_AND_ENUM_SUFFIX :
+ key = new char[] {ONE_STAR[0], SEPARATOR, ONE_STAR[0]};
break;
}
} else if (this.simpleName[this.simpleName.length - 1] != '*') {
@@ -231,6 +323,12 @@
case CLASS_SUFFIX :
output.append("ClassDeclarationPattern: pkg<"); //$NON-NLS-1$
break;
+ case CLASS_AND_INTERFACE_SUFFIX:
+ output.append("ClassAndInterfaceDeclarationPattern: pkg<"); //$NON-NLS-1$
+ break;
+ case CLASS_AND_ENUM_SUFFIX :
+ output.append("ClassAndEnumDeclarationPattern: pkg<"); //$NON-NLS-1$
+ break;
case INTERFACE_SUFFIX :
output.append("InterfaceDeclarationPattern: pkg<"); //$NON-NLS-1$
break;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
index 8588f90..685c0d4 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
@@ -43,6 +43,9 @@
element = element.getParent();
return element;
}
+public int match(Annotation node, MatchingNodeSet nodeSet) {
+ return match(node.type, nodeSet);
+}
public int match(ASTNode node, MatchingNodeSet nodeSet) { // interested in ImportReference
if (!(node instanceof ImportReference)) return IMPOSSIBLE_MATCH;
@@ -196,7 +199,7 @@
}
if (typeBinding instanceof ProblemReferenceBinding) {
ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding;
- typeBinding = pbBinding.original;
+ typeBinding = pbBinding.closestMatch;
lastIndex = pbBinding.compoundName.length - 1;
}
// try to match all enclosing types for which the token matches as well.
@@ -295,7 +298,7 @@
}
if (typeBinding instanceof ProblemReferenceBinding) {
ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding;
- typeBinding = pbBinding.original;
+ typeBinding = pbBinding.closestMatch;
lastIndex = pbBinding.compoundName.length - 1;
}
@@ -309,11 +312,19 @@
if (resolveLevelForType(refBinding) == ACCURATE_MATCH) {
if (locator.encloses(element)) {
long[] positions = qNameRef.sourcePositions;
- int start = (int) ((positions[this.pattern.qualification == null ? lastIndex : 0]) >>> 32);
+ // index now depends on pattern type signature
+ int index = lastIndex;
+ if (this.pattern.qualification != null) {
+ index = lastIndex - this.pattern.segmentsSize;
+ }
+ if (index < 0) index = 0;
+ int start = (int) ((positions[index]) >>> 32);
int end = (int) positions[lastIndex];
match.setOffset(start);
match.setLength(end-start+1);
- locator.report(match);
+
+ // Look if there's a need to special report for parameterized type
+ matchReportReference(qNameRef, lastIndex, refBinding, locator);
}
return;
}
@@ -330,7 +341,7 @@
typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
if (typeBinding instanceof ProblemReferenceBinding) {
ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding;
- typeBinding = pbBinding.original;
+ typeBinding = pbBinding.closestMatch;
lastIndex = pbBinding.compoundName.length - 1;
}
@@ -404,9 +415,20 @@
// Report match
if (expr instanceof ArrayTypeReference) {
locator.reportAccurateTypeReference(match, expr, this.pattern.simpleName);
- } else {
- locator.report(match);
+ return;
}
+ if (refBinding.isLocalType()) {
+ // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=82673
+ LocalTypeBinding local = (LocalTypeBinding) refBinding;
+ IJavaElement focus = ((InternalSearchPattern)pattern).focus;
+ if (focus != null && local.enclosingMethod != null && focus.getParent().getElementType() == IJavaElement.METHOD) {
+ IMethod method = (IMethod) focus.getParent();
+ if (!CharOperation.equals(local.enclosingMethod.selector, method.getElementName().toCharArray())) {
+ return;
+ }
+ }
+ }
+ locator.report(match);
}
protected int referenceType() {
return IJavaElement.TYPE;
@@ -453,7 +475,7 @@
typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
if (typeBinding == null || typeBinding instanceof BaseTypeBinding) return;
if (typeBinding instanceof ProblemReferenceBinding) {
- ReferenceBinding original = ((ProblemReferenceBinding) typeBinding).original;
+ ReferenceBinding original = ((ProblemReferenceBinding) typeBinding).closestMatch;
if (original == null) return; // original may not be set (bug 71279)
typeBinding = original;
}
@@ -515,7 +537,7 @@
if (typeBinding instanceof ArrayBinding)
typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
if (typeBinding instanceof ProblemReferenceBinding)
- typeBinding = ((ProblemReferenceBinding) typeBinding).original;
+ typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch;
if (((InternalSearchPattern) this.pattern).focus instanceof IType && typeBinding instanceof ReferenceBinding) {
IPackageFragment pkg = ((IType) ((InternalSearchPattern) this.pattern).focus).getPackageFragment();
@@ -531,7 +553,7 @@
if (nameRef instanceof SingleNameReference) {
if (binding instanceof ProblemReferenceBinding)
- binding = ((ProblemReferenceBinding) binding).original;
+ binding = ((ProblemReferenceBinding) binding).closestMatch;
if (binding instanceof ReferenceBinding)
return resolveLevelForType((ReferenceBinding) binding);
return binding == null || binding instanceof ProblemBinding ? INACCURATE_MATCH : IMPOSSIBLE_MATCH;
@@ -578,7 +600,7 @@
if (typeBinding instanceof ArrayBinding)
typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
if (typeBinding instanceof ProblemReferenceBinding)
- typeBinding = ((ProblemReferenceBinding) typeBinding).original;
+ typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch;
if (typeRef instanceof SingleTypeReference) {
return resolveLevelForType(typeBinding);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
index e523a16..6f752e1 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
@@ -28,6 +28,7 @@
/* background processing */
protected Thread processingThread;
+ protected Job progressJob;
/* counter indicating whether job execution is enabled or not, disabled if <= 0
it cannot go beyond 1 */
@@ -198,7 +199,6 @@
case IJob.CancelIfNotReady :
if (VERBOSE)
Util.verbose("-> NOT READY - cancelling - " + searchJob); //$NON-NLS-1$
- if (progress != null) progress.setCanceled(true);
if (VERBOSE)
Util.verbose("CANCELED concurrent job - " + searchJob); //$NON-NLS-1$
throw new OperationCanceledException();
@@ -317,7 +317,7 @@
}
protected IStatus run(IProgressMonitor monitor) {
int awaitingJobsCount;
- while ((awaitingJobsCount = awaitingJobsCount()) > 0) {
+ while (!monitor.isCanceled() && (awaitingJobsCount = awaitingJobsCount()) > 0) {
monitor.subTask(Messages.bind(Messages.manager_filesToIndex, Integer.toString(awaitingJobsCount)));
try {
Thread.sleep(500);
@@ -328,7 +328,7 @@
return Status.OK_STATUS;
}
}
- ProgressJob progressJob = null;
+ this.progressJob = null;
while (this.processingThread != null) {
try {
IJob job;
@@ -338,7 +338,10 @@
// must check for new job inside this sync block to avoid timing hole
if ((job = currentJob()) == null) {
- if (progressJob != null) progressJob = null;
+ if (this.progressJob != null) {
+ this.progressJob.cancel();
+ this.progressJob = null;
+ }
if (idlingStart < 0)
idlingStart = System.currentTimeMillis();
else
@@ -360,11 +363,11 @@
}
try {
this.executing = true;
- if (progressJob == null) {
- progressJob = new ProgressJob(Messages.manager_indexingInProgress);
- progressJob.setPriority(Job.LONG);
- progressJob.setSystem(true);
- progressJob.schedule();
+ if (this.progressJob == null) {
+ this.progressJob = new ProgressJob(Messages.manager_indexingInProgress);
+ this.progressJob.setPriority(Job.LONG);
+ this.progressJob.setSystem(true);
+ this.progressJob.schedule();
}
/*boolean status = */job.execute(null);
//if (status == FAILED) request(job);
@@ -423,6 +426,11 @@
// in case processing thread is handling a job
thread.join();
}
+ Job job = this.progressJob;
+ if (job != null) {
+ job.cancel();
+ job.join();
+ }
} catch (InterruptedException e) {
// ignore
}