diff options
Diffstat (limited to 'org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching')
5 files changed, 372 insertions, 24 deletions
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 6e8e133ca..48e281952 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2016 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 @@ -18,10 +18,9 @@ import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.search.*; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.classfmt.FieldInfo; -import org.eclipse.jdt.internal.compiler.classfmt.MethodInfo; import org.eclipse.jdt.internal.compiler.env.*; import org.eclipse.jdt.internal.compiler.lookup.*; +import org.eclipse.jdt.internal.core.BinaryType; import org.eclipse.jdt.internal.core.*; import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants; @@ -352,10 +351,10 @@ private void matchAnnotations(SearchPattern pattern, MatchLocator locator, Class } // Look for references in methods annotations - MethodInfo[] methods = (MethodInfo[]) binaryType.getMethods(); + IBinaryMethod[] methods = binaryType.getMethods(); if (methods != null) { for (int i = 0, max = methods.length; i < max; i++) { - MethodInfo method = methods[i]; + IBinaryMethod method = methods[i]; if (checkAnnotations(typeReferencePattern, method.getAnnotations(), method.getTagBits())) { binaryTypeBinding = locator.cacheBinaryType(classFileBinaryType, binaryType); IMethod methodHandle = classFileBinaryType.getMethod( @@ -370,10 +369,10 @@ private void matchAnnotations(SearchPattern pattern, MatchLocator locator, Class } // Look for references in fields annotations - FieldInfo[] fields = (FieldInfo[]) binaryType.getFields(); + IBinaryField[] fields = binaryType.getFields(); if (fields != null) { for (int i = 0, max = fields.length; i < max; i++) { - FieldInfo field = fields[i]; + IBinaryField field = fields[i]; if (checkAnnotations(typeReferencePattern, field.getAnnotations(), field.getTagBits())) { IField fieldHandle = classFileBinaryType.getField(new String(field.getName())); TypeReferenceMatch match = new TypeReferenceMatch(fieldHandle, SearchMatch.A_ACCURATE, -1, 0, false, locator.getParticipant(), locator.currentPossibleMatch.resource); diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java new file mode 100644 index 000000000..907707501 --- /dev/null +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/IndexBasedJavaSearchEnvironment.java @@ -0,0 +1,333 @@ +/******************************************************************************* + * Copyright (c) 2015, 2016 Google, Inc 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: + * Stefan Xenos (Google) - Initial implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.search.matching; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaProject; +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.compiler.env.AccessRestriction; +import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; +import org.eclipse.jdt.internal.compiler.env.IBinaryType; +import org.eclipse.jdt.internal.compiler.env.INameEnvironment; +import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; +import org.eclipse.jdt.internal.compiler.util.SuffixConstants; +import org.eclipse.jdt.internal.core.ClasspathEntry; +import org.eclipse.jdt.internal.core.JavaModel; +import org.eclipse.jdt.internal.core.JavaProject; +import org.eclipse.jdt.internal.core.PackageFragmentRoot; +import org.eclipse.jdt.internal.core.builder.ClasspathLocation; +import org.eclipse.jdt.internal.core.nd.IReader; +import org.eclipse.jdt.internal.core.nd.Nd; +import org.eclipse.jdt.internal.core.nd.field.FieldSearchIndex; +import org.eclipse.jdt.internal.core.nd.java.JavaIndex; +import org.eclipse.jdt.internal.core.nd.java.JavaNames; +import org.eclipse.jdt.internal.core.nd.java.NdResourceFile; +import org.eclipse.jdt.internal.core.nd.java.NdType; +import org.eclipse.jdt.internal.core.nd.java.NdTypeId; +import org.eclipse.jdt.internal.core.nd.java.TypeRef; +import org.eclipse.jdt.internal.core.nd.java.model.IndexBinaryType; +import org.eclipse.jdt.internal.core.nd.util.CharArrayUtils; +import org.eclipse.jdt.internal.core.nd.util.PathMap; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class IndexBasedJavaSearchEnvironment implements INameEnvironment, SuffixConstants { + + private Map<String, ICompilationUnit> workingCopies; + private PathMap<Integer> mapPathsToRoots = new PathMap<>(); + private IPackageFragmentRoot[] roots; + private int sourceEntryPosition; + private List<ClasspathLocation> unindexedEntries = new ArrayList<>(); + + public IndexBasedJavaSearchEnvironment(List<IJavaProject> javaProject, org.eclipse.jdt.core.ICompilationUnit[] copies) { + this.workingCopies = JavaSearchNameEnvironment.getWorkingCopyMap(copies); + + try { + List<IPackageFragmentRoot> localRoots = new ArrayList<>(); + + for (IJavaProject next : javaProject) { + for (IPackageFragmentRoot nextRoot : next.getAllPackageFragmentRoots()) { + IPath path = nextRoot.getPath(); + if (!nextRoot.isArchive()) { + Object target = JavaModel.getTarget(path, true); + if (target != null) { + ClasspathLocation cp; + if (nextRoot.getKind() == IPackageFragmentRoot.K_SOURCE) { + PackageFragmentRoot root = (PackageFragmentRoot)nextRoot; + cp = new ClasspathSourceDirectory((IContainer)target, root.fullExclusionPatternChars(), root.fullInclusionPatternChars()); + this.unindexedEntries.add(cp); + } + } + } + + localRoots.add(nextRoot); + } + } + + this.roots = localRoots.toArray(new IPackageFragmentRoot[0]); + } catch (JavaModelException e) { + this.roots = new IPackageFragmentRoot[0]; + // project doesn't exist + } + + // Build the map of paths onto root indices + int length = this.roots.length; + for (int i = 0; i < length; i++) { + IPath nextPath = JavaIndex.getLocationForElement(this.roots[i]); + this.mapPathsToRoots.put(nextPath, i); + } + + // Locate the position of the first source entry + this.sourceEntryPosition = Integer.MAX_VALUE; + for (int i = 0; i < length; i++) { + IPackageFragmentRoot nextRoot = this.roots[i]; + try { + if (nextRoot.getKind() == IPackageFragmentRoot.K_SOURCE) { + this.sourceEntryPosition = i; + break; + } + } catch (JavaModelException e) { + // project doesn't exist + } + } + } + + public static boolean isEnabled() { + return Platform.getPreferencesService().getBoolean(JavaCore.PLUGIN_ID, "useIndexBasedSearchEnvironment", false, //$NON-NLS-1$ + null); + } + + @Override + public NameEnvironmentAnswer findType(char[][] compoundTypeName) { + char[] binaryName = CharOperation.concatWith(compoundTypeName, '/'); + + int bestEntryPosition = Integer.MAX_VALUE; + NameEnvironmentAnswer result = findClassInUnindexedLocations(new String(binaryName), compoundTypeName[compoundTypeName.length - 1]); + if (result != null) { + bestEntryPosition = this.sourceEntryPosition; + } + + char[] fieldDescriptor = JavaNames.binaryNameToFieldDescriptor(binaryName); + JavaIndex index = JavaIndex.getIndex(); + Nd nd = index.getNd(); + try (IReader lock = nd.acquireReadLock()) { + NdTypeId typeId = index.findType(fieldDescriptor); + + if (typeId != null) { + List<NdType> types = typeId.getTypes(); + for (NdType next : types) { + NdResourceFile resource = next.getFile(); + + IPath path = resource.getPath(); + Integer nextRoot = this.mapPathsToRoots.getMostSpecific(path); + if (nextRoot != null) { + IPackageFragmentRoot root = this.roots[nextRoot]; + + ClasspathEntry classpathEntry = (ClasspathEntry)root.getRawClasspathEntry(); + AccessRuleSet ruleSet = classpathEntry.getAccessRuleSet(); + AccessRestriction accessRestriction = ruleSet == null? null : ruleSet.getViolatedRestriction(binaryName); + TypeRef typeRef = TypeRef.create(next); + String fileName = new String(binaryName) + ".class"; //$NON-NLS-1$ + IBinaryType binaryType = new IndexBinaryType(typeRef, fileName.toCharArray()); + NameEnvironmentAnswer nextAnswer = new NameEnvironmentAnswer(binaryType, accessRestriction); + + boolean useNewAnswer = isBetter(result, bestEntryPosition, nextAnswer, nextRoot); + + if (useNewAnswer) { + bestEntryPosition = nextRoot; + result = nextAnswer; + } + } + } + } + } catch (JavaModelException e) { + // project doesn't exist + } + + return result; + } + + /** + * Search unindexed locations on the classpath for the given class + */ + private NameEnvironmentAnswer findClassInUnindexedLocations(String qualifiedTypeName, char[] typeName) { + String + binaryFileName = null, qBinaryFileName = null, + sourceFileName = null, qSourceFileName = null, + qPackageName = null; + NameEnvironmentAnswer suggestedAnswer = null; + Iterator <ClasspathLocation> iter = this.unindexedEntries.iterator(); + while (iter.hasNext()) { + ClasspathLocation location = iter.next(); + NameEnvironmentAnswer answer; + if (location instanceof ClasspathSourceDirectory) { + if (sourceFileName == null) { + qSourceFileName = qualifiedTypeName; // doesn't include the file extension + sourceFileName = qSourceFileName; + qPackageName = ""; //$NON-NLS-1$ + if (qualifiedTypeName.length() > typeName.length) { + int typeNameStart = qSourceFileName.length() - typeName.length; + qPackageName = qSourceFileName.substring(0, typeNameStart - 1); + sourceFileName = qSourceFileName.substring(typeNameStart); + } + } + org.eclipse.jdt.internal.compiler.env.ICompilationUnit workingCopy = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) this.workingCopies.get(qualifiedTypeName); + if (workingCopy != null) { + answer = new NameEnvironmentAnswer(workingCopy, null /*no access restriction*/); + } else { + answer = location.findClass( + sourceFileName, // doesn't include the file extension + qPackageName, + qSourceFileName); // doesn't include the file extension + } + } else { + if (binaryFileName == null) { + qBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class; + binaryFileName = qBinaryFileName; + qPackageName = ""; //$NON-NLS-1$ + if (qualifiedTypeName.length() > typeName.length) { + int typeNameStart = qBinaryFileName.length() - typeName.length - 6; // size of ".class" + qPackageName = qBinaryFileName.substring(0, typeNameStart - 1); + binaryFileName = qBinaryFileName.substring(typeNameStart); + } + } + answer = + location.findClass( + binaryFileName, + qPackageName, + qBinaryFileName); + } + if (answer != null) { + if (!answer.ignoreIfBetter()) { + if (answer.isBetter(suggestedAnswer)) + return answer; + } else if (answer.isBetter(suggestedAnswer)) + // remember suggestion and keep looking + suggestedAnswer = answer; + } + } + if (suggestedAnswer != null) + // no better answer was found + return suggestedAnswer; + return null; + } + + public boolean isBetter(NameEnvironmentAnswer currentBest, int currentBestClasspathPosition, + NameEnvironmentAnswer toTest, int toTestClasspathPosition) { + boolean useNewAnswer = false; + + if (currentBest == null) { + useNewAnswer = true; + } else { + if (toTest.isBetter(currentBest)) { + useNewAnswer = true; + } else { + // If neither one is better, use the one with the earlier classpath position + if (!currentBest.isBetter(toTest)) { + useNewAnswer = (toTestClasspathPosition < currentBestClasspathPosition); + } + } + } + return useNewAnswer; + } + + @Override + public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { + char[][] newArray = new char[packageName.length + 1][]; + for (int idx = 0; idx < packageName.length; idx++) { + newArray[idx] = packageName[idx]; + } + newArray[packageName.length] = typeName; + return findType(newArray); + } + + @Override + public boolean isPackage(char[][] parentPackageName, char[] packageName) { + char[] binaryPackageName = CharOperation.concatWith(parentPackageName, '/'); + final char[] fieldDescriptorPrefix; + + if (parentPackageName == null || parentPackageName.length == 0) { + fieldDescriptorPrefix = CharArrayUtils.concat(JavaNames.FIELD_DESCRIPTOR_PREFIX, packageName, + new char[] { '/' }); + } else { + fieldDescriptorPrefix = CharArrayUtils.concat(JavaNames.FIELD_DESCRIPTOR_PREFIX, binaryPackageName, + new char[] { '/' }, packageName, new char[] { '/' }); + } + + // Search all the types that are a subpackage of the given package name. Return if we find any one of them on + // the classpath of this project. + JavaIndex index = JavaIndex.getIndex(); + Nd nd = index.getNd(); + try (IReader lock = nd.acquireReadLock()) { + return !index.visitFieldDescriptorsStartingWith(fieldDescriptorPrefix, + new FieldSearchIndex.Visitor<NdTypeId>() { + @Override + public boolean visit(NdTypeId typeId) { + //String fd = typeId.getFieldDescriptor().getString(); + // If this is an exact match for the field descriptor prefix we're looking for then + // this class can't be part of the package we're searching for (and, most likely, the + // "package" we're searching for is actually a class name - not a package). + if (typeId.getFieldDescriptor().length() <= fieldDescriptorPrefix.length + 1) { + return true; + } + List<NdType> types = typeId.getTypes(); + for (NdType next : types) { + if (next.isMember() || next.isLocal() || next.isAnonymous()) { + continue; + } + NdResourceFile resource = next.getFile(); + + IPath path = resource.getPath(); + + if (containsPrefixOf(path)) { + // Terminate the search -- we've found a class belonging to the package + // we're searching for. + return false; + } + } + return true; + } + }); + } + } + + boolean containsPrefixOf(IPath path) { + return this.mapPathsToRoots.containsPrefixOf(path); + } + + @Override + public void cleanup() { + // No explicit cleanup required for this class + } + + public static INameEnvironment create(List<IJavaProject> javaProjects, org.eclipse.jdt.core.ICompilationUnit[] copies) { + if (JavaIndex.isEnabled() && isEnabled()) { + return new IndexBasedJavaSearchEnvironment(javaProjects, copies); + } else { + Iterator<IJavaProject> next = javaProjects.iterator(); + JavaSearchNameEnvironment result = new JavaSearchNameEnvironment(next.next(), copies); + + while (next.hasNext()) { + result.addProjectClassPath((JavaProject)next.next()); + } + return result; + } + } +} diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java index 9a115722f..0c7de1594 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java @@ -15,11 +15,15 @@ package org.eclipse.jdt.internal.core.search.matching; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; +import java.util.Map; import org.eclipse.core.resources.IContainer; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; -import org.eclipse.jdt.core.*; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageDeclaration; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.env.INameEnvironment; @@ -39,19 +43,24 @@ import org.eclipse.jdt.internal.core.util.Util; */ @SuppressWarnings({"rawtypes", "unchecked"}) public class JavaSearchNameEnvironment implements INameEnvironment, SuffixConstants { - + LinkedHashSet<ClasspathLocation> locationSet; /* * A map from the fully qualified slash-separated name of the main type (String) to the working copy */ - HashMap workingCopies; - + Map<String, org.eclipse.jdt.core.ICompilationUnit> workingCopies; + public JavaSearchNameEnvironment(IJavaProject javaProject, org.eclipse.jdt.core.ICompilationUnit[] copies) { this.locationSet = computeClasspathLocations((JavaProject) javaProject); + this.workingCopies = getWorkingCopyMap(copies); +} + +public static Map<String, org.eclipse.jdt.core.ICompilationUnit> getWorkingCopyMap( + org.eclipse.jdt.core.ICompilationUnit[] copies) { + int length = copies == null ? 0 : copies.length; + HashMap<String, org.eclipse.jdt.core.ICompilationUnit> result = new HashMap<>(length); try { - int length = copies == null ? 0 : copies.length; - this.workingCopies = new HashMap(length); if (copies != null) { for (int i = 0; i < length; i++) { org.eclipse.jdt.core.ICompilationUnit workingCopy = copies[i]; @@ -60,12 +69,13 @@ public JavaSearchNameEnvironment(IJavaProject javaProject, org.eclipse.jdt.core. String cuName = workingCopy.getElementName(); String mainTypeName = Util.getNameWithoutJavaLikeExtension(cuName); String qualifiedMainTypeName = pkg.length() == 0 ? mainTypeName : pkg.replace('.', '/') + '/' + mainTypeName; - this.workingCopies.put(qualifiedMainTypeName, workingCopy); + result.put(qualifiedMainTypeName, workingCopy); } } } catch (JavaModelException e) { // working copy doesn't exist: cannot happen } + return result; } public void cleanup() { 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 48094d331..1630f54f9 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 @@ -294,11 +294,11 @@ private static HashMap workingCopiesThatCanSeeFocus(org.eclipse.jdt.core.ICompil return result; } -public static ClassFileReader classFileReader(IType type) { +public static IBinaryType classFileReader(IType type) { IClassFile classFile = type.getClassFile(); JavaModelManager manager = JavaModelManager.getJavaModelManager(); if (classFile.isOpen()) - return (ClassFileReader) manager.getInfo(type); + return (IBinaryType)manager.getInfo(type); PackageFragment pkg = (PackageFragment) type.getPackageFragment(); IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent(); @@ -549,7 +549,7 @@ protected IJavaElement createHandle(AbstractMethodDeclaration method, IJavaEleme if (type.isBinary()) { // don't cache the methods of the binary type // fall thru if its a constructor with a synthetic argument... find it the slower way - ClassFileReader reader = classFileReader(type); + IBinaryType reader = classFileReader(type); if (reader != null) { // build arguments names boolean firstIsSynthetic = false; @@ -619,7 +619,7 @@ protected IJavaElement createHandle(AbstractMethodDeclaration method, IJavaEleme * Create binary method handle */ IMethod createBinaryMethodHandle(IType type, char[] methodSelector, char[][] argumentTypeNames) { - ClassFileReader reader = MatchLocator.classFileReader(type); + IBinaryType reader = MatchLocator.classFileReader(type); if (reader != null) { IBinaryMethod[] methods = reader.getMethods(); if (methods != null) { @@ -1271,9 +1271,15 @@ public void initialize(JavaProject project, int possibleMatchSize) throws JavaMo SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(this.workingCopies); - this.nameEnvironment = new JavaSearchNameEnvironment(project, this.workingCopies); - if (this.pattern.focus != null) - ((JavaSearchNameEnvironment) this.nameEnvironment).addProjectClassPath((JavaProject) this.pattern.focus.getJavaProject()); + List<IJavaProject> projects = new ArrayList<>(); + projects.add(project); + if (this.pattern.focus != null) { + IJavaProject focusProject = this.pattern.focus.getJavaProject(); + if (focusProject != project) { + projects.add(focusProject); + } + } + this.nameEnvironment = IndexBasedJavaSearchEnvironment.create(projects, this.workingCopies); // create lookup environment Map map = project.getOptions(true); 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 3cd748ce1..88f084a64 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2016 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 @@ -15,7 +15,7 @@ import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.search.SearchDocument; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; +import org.eclipse.jdt.internal.compiler.env.IBinaryType; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.core.*; import org.eclipse.jdt.internal.core.util.Util; @@ -135,7 +135,7 @@ private String getSourceFileName() { this.sourceFileName = NO_SOURCE_FILE_NAME; if (this.openable.getSourceMapper() != null) { BinaryType type = (BinaryType) ((ClassFile) this.openable).getType(); - ClassFileReader reader = MatchLocator.classFileReader(type); + IBinaryType reader = MatchLocator.classFileReader(type); if (reader != null) { String fileName = type.sourceFileName(reader); this.sourceFileName = fileName == null ? NO_SOURCE_FILE_NAME : fileName; |