mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 16:17:34 +00:00
Incomplete work on pseudo-resolving something like "@Getter" to: Yes, this is almost certainly intended to be lombok.Getter, so get to work!
This commit is contained in:
1 parent
e84bdd32e7
commit
5dca3b7eea
2 files changed
+133
No files matched your search
@@ -0,0 +1,38 @@
|
||||
package lombok.transformations;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class TypeLibrary {
|
||||
private final Map<String, Set<String>> simpleToQualifiedMap = new HashMap<String, Set<String>>();
|
||||
|
||||
public void addType(String fullyQualifiedTypeName) {
|
||||
int idx = fullyQualifiedTypeName.lastIndexOf('.');
|
||||
if ( idx == -1 ) throw new IllegalArgumentException(
|
||||
"Only fully qualified types are allowed (and stuff in the default package is not palatable to us either!)");
|
||||
|
||||
final String simpleName = fullyQualifiedTypeName.substring(idx +1);
|
||||
final String packageName = fullyQualifiedTypeName.substring(0, idx);
|
||||
|
||||
if ( simpleToQualifiedMap.put(fullyQualifiedTypeName, Collections.singleton(fullyQualifiedTypeName)) != null ) return;
|
||||
|
||||
addToMap(simpleName, fullyQualifiedTypeName);
|
||||
addToMap(packageName + ".*", fullyQualifiedTypeName);
|
||||
}
|
||||
|
||||
private TypeLibrary addToMap(String keyName, String fullyQualifiedTypeName) {
|
||||
Set<String> existing = simpleToQualifiedMap.get(keyName);
|
||||
Set<String> set = (existing == null) ? new HashSet<String>() : new HashSet<String>(existing);
|
||||
set.add(fullyQualifiedTypeName);
|
||||
simpleToQualifiedMap.put(keyName, Collections.unmodifiableSet(set));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Collection<String> findCompatible(String typeReference) {
|
||||
return simpleToQualifiedMap.get(typeReference);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package lombok.transformations;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.eclipse.EclipseAST;
|
||||
|
||||
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
|
||||
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
|
||||
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
|
||||
import org.eclipse.jdt.internal.compiler.parser.Parser;
|
||||
|
||||
public class TypeResolver {
|
||||
private final TypeLibrary library;
|
||||
private final EclipseAST ast;
|
||||
private Collection<String> imports;
|
||||
|
||||
|
||||
public TypeResolver(TypeLibrary library, Parser parser, EclipseAST ast) {
|
||||
this.library = library;
|
||||
this.ast = ast;
|
||||
this.imports = makeImportList((CompilationUnitDeclaration) ast.top().getEclipseNode());
|
||||
}
|
||||
|
||||
private static Collection<String> makeImportList(CompilationUnitDeclaration declaration) {
|
||||
Set<String> imports = new HashSet<String>();
|
||||
if ( declaration.currentPackage != null ) imports.add(toQualifiedName(declaration.currentPackage.getImportName()) + ".*");
|
||||
if ( declaration.imports != null ) for ( ImportReference importStatement : declaration.imports ) {
|
||||
imports.add(toQualifiedName(importStatement.getImportName()));
|
||||
}
|
||||
return imports;
|
||||
}
|
||||
|
||||
public Collection<String> findTypeMatches(ASTNode context, TypeReference type) {
|
||||
Collection<String> potentialMatches = library.findCompatible(toQualifiedName(type.getTypeName()));
|
||||
if ( potentialMatches.isEmpty() ) return Collections.emptyList();
|
||||
|
||||
if ( type.getTypeName().length > 1 ) return potentialMatches;
|
||||
|
||||
String simpleName = new String(type.getTypeName()[0]);
|
||||
|
||||
//If there's an import statement that explicitly imports a 'Getter' that isn't any of our potentials, return no matches.
|
||||
if ( nameConflictInImportList(simpleName, potentialMatches) ) return Collections.emptyList();
|
||||
|
||||
//Check if any of our potentials is even imported in the first place. If not: no matches.
|
||||
potentialMatches = eliminateImpossibleMatches(potentialMatches);
|
||||
if ( potentialMatches.isEmpty() ) return Collections.emptyList();
|
||||
|
||||
//Find a lexically accessible type of the same simple name in the same Compilation Unit. If it exists: no matches.
|
||||
|
||||
|
||||
// The potential matches we found by comparing the import statements is our matching set. Return it.
|
||||
return potentialMatches;
|
||||
}
|
||||
|
||||
private Collection<String> eliminateImpossibleMatches(Collection<String> potentialMatches) {
|
||||
Set<String> results = new HashSet<String>();
|
||||
|
||||
for ( String importedType : imports ) {
|
||||
Collection<String> reduced = library.findCompatible(importedType);
|
||||
reduced.retainAll(potentialMatches);
|
||||
results.addAll(reduced);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private boolean nameConflictInImportList(String simpleName, Collection<String> potentialMatches) {
|
||||
for ( String importedType : imports ) {
|
||||
if ( !toSimpleName(importedType).equals(simpleName) ) continue;
|
||||
if ( potentialMatches.contains(importedType) ) continue;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String toSimpleName(String typeName) {
|
||||
int idx = typeName.lastIndexOf('.');
|
||||
return idx == -1 ? typeName : typeName.substring(idx+1);
|
||||
}
|
||||
|
||||
private static String toQualifiedName(char[][] typeName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean first = true;
|
||||
for ( char[] c : typeName ) {
|
||||
sb.append(first ? "" : ".").append(c);
|
||||
first = false;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user