use of org.codehaus.groovy.ast.ImportNode in project groovy by apache.
the class AntlrParserPlugin method importDef.
protected void importDef(AST importNode) {
try {
// GROOVY-6094
output.putNodeMetaData(ImportNode.class, ImportNode.class);
boolean isStatic = importNode.getType() == STATIC_IMPORT;
List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
AST node = importNode.getFirstChild();
if (isType(ANNOTATIONS, node)) {
processAnnotations(annotations, node);
node = node.getNextSibling();
}
String alias = null;
if (isType(LITERAL_as, node)) {
//import is like "import Foo as Bar"
node = node.getFirstChild();
AST aliasNode = node.getNextSibling();
alias = identifier(aliasNode);
}
if (node.getNumberOfChildren() == 0) {
String name = identifier(node);
// import is like "import Foo"
ClassNode type = ClassHelper.make(name);
configureAST(type, importNode);
addImport(type, name, alias, annotations);
return;
}
AST packageNode = node.getFirstChild();
String packageName = qualifiedName(packageNode);
AST nameNode = packageNode.getNextSibling();
if (isType(STAR, nameNode)) {
if (isStatic) {
// import is like "import static foo.Bar.*"
// packageName is actually a className in this case
ClassNode type = ClassHelper.make(packageName);
configureAST(type, importNode);
addStaticStarImport(type, packageName, annotations);
} else {
// import is like "import foo.*"
addStarImport(packageName, annotations);
}
if (alias != null)
throw new GroovyBugError("imports like 'import foo.* as Bar' are not " + "supported and should be caught by the grammar");
} else {
String name = identifier(nameNode);
if (isStatic) {
// import is like "import static foo.Bar.method"
// packageName is really class name in this case
ClassNode type = ClassHelper.make(packageName);
configureAST(type, importNode);
addStaticImport(type, name, alias, annotations);
} else {
// import is like "import foo.Bar"
ClassNode type = ClassHelper.make(packageName + "." + name);
configureAST(type, importNode);
addImport(type, name, alias, annotations);
}
}
} finally {
// we're using node metadata here in order to fix GROOVY-6094
// without breaking external APIs
Object node = output.getNodeMetaData(ImportNode.class);
if (node != null && node != ImportNode.class) {
configureAST((ImportNode) node, importNode);
}
output.removeNodeMetaData(ImportNode.class);
}
}
use of org.codehaus.groovy.ast.ImportNode in project groovy by apache.
the class StaticImportVisitor method findStaticFieldOrPropAccessorImportFromModule.
private Expression findStaticFieldOrPropAccessorImportFromModule(String name) {
ModuleNode module = currentClass.getModule();
if (module == null)
return null;
Map<String, ImportNode> importNodes = module.getStaticImports();
Expression expression;
String accessorName = getAccessorName(name);
// when resolving prop reference
if (importNodes.containsKey(accessorName)) {
expression = findStaticProperty(importNodes, accessorName);
if (expression != null)
return expression;
}
if (accessorName.startsWith("get")) {
accessorName = "is" + accessorName.substring(3);
if (importNodes.containsKey(accessorName)) {
expression = findStaticProperty(importNodes, accessorName);
if (expression != null)
return expression;
}
}
// when resolving prop or field reference
if (importNodes.containsKey(name)) {
ImportNode importNode = importNodes.get(name);
expression = findStaticPropertyAccessor(importNode.getType(), importNode.getFieldName());
if (expression != null)
return expression;
expression = findStaticField(importNode.getType(), importNode.getFieldName());
if (expression != null)
return expression;
}
// when resolving prop or field reference
for (ImportNode importNode : module.getStaticStarImports().values()) {
ClassNode node = importNode.getType();
expression = findStaticPropertyAccessor(node, name);
if (expression != null)
return expression;
expression = findStaticField(node, name);
if (expression != null)
return expression;
}
return null;
}
use of org.codehaus.groovy.ast.ImportNode in project gradle by gradle.
the class GradleResolveVisitor method resolveAliasFromModule.
private boolean resolveAliasFromModule(ClassNode type) {
// node and any subclass resolving will then take place elsewhere
if (type instanceof ConstructedClassWithPackage) {
return false;
}
ModuleNode module = currentClass.getModule();
if (module == null) {
return false;
}
String name = type.getName();
// check module node imports aliases
// the while loop enables a check for inner classes which are not fully imported,
// but visible as the surrounding class is imported and the inner class is public/protected static
String pname = name;
int index = name.length();
/*
* we have a name foo.bar and an import foo.foo. This means foo.bar is possibly
* foo.foo.bar rather than foo.bar. This means to cut at the dot in foo.bar and
* foo for import
*/
while (true) {
pname = name.substring(0, index);
ClassNode aliasedNode = null;
ImportNode importNode = module.getImport(pname);
if (importNode != null && importNode != currImportNode) {
aliasedNode = importNode.getType();
}
if (aliasedNode == null) {
importNode = module.getStaticImports().get(pname);
if (importNode != null && importNode != currImportNode) {
// static alias only for inner classes and must be at end of chain
ClassNode tmp = new ConstructedNestedClass(importNode.getType(), importNode.getFieldName());
if (resolve(tmp, false, false, true)) {
if ((tmp.getModifiers() & Opcodes.ACC_STATIC) != 0) {
type.setRedirect(tmp.redirect());
return true;
}
}
}
}
if (aliasedNode != null) {
if (pname.length() == name.length()) {
// full match
// We can compare here by length, because pname is always
// a substring of name, so same length means they are equal.
type.setRedirect(aliasedNode);
return true;
} else {
// partial match
// At this point we know that we have a match for pname. This may
// mean, that name[pname.length()..<-1] is a static inner class.
// For this the rest of the name does not need any dots in its name.
// It is either completely a inner static class or it is not.
// Since we do not want to have useless lookups we create the name
// completely and use a ConstructedClassWithPackage to prevent lookups against the package.
String className = aliasedNode.getNameWithoutPackage() + '$' + name.substring(pname.length() + 1).replace('.', '$');
ConstructedClassWithPackage tmp = new ConstructedClassWithPackage(aliasedNode.getPackageName() + ".", className);
if (resolve(tmp, true, true, false)) {
type.setRedirect(tmp.redirect());
return true;
}
}
}
index = pname.lastIndexOf('.');
if (index == -1) {
break;
}
}
return false;
}
use of org.codehaus.groovy.ast.ImportNode in project gradle by gradle.
the class GradleResolveVisitor method resolveFromModule.
private boolean resolveFromModule(ClassNode type, boolean testModuleImports) {
if (type instanceof ConstructedNestedClass) {
return false;
}
// with a lower case letter anymore
if (type instanceof LowerCaseClass) {
return resolveAliasFromModule(type);
}
String name = type.getName();
ModuleNode module = currentClass.getModule();
if (module == null) {
return false;
}
boolean newNameUsed = false;
// fact. We check here for ConstructedClassWithPackage.
if (!type.hasPackageName() && module.hasPackageName() && !(type instanceof ConstructedClassWithPackage)) {
type.setName(module.getPackageName() + name);
newNameUsed = true;
}
// look into the module node if there is a class with that name
List<ClassNode> moduleClasses = module.getClasses();
for (ClassNode mClass : moduleClasses) {
if (mClass.getName().equals(type.getName())) {
if (mClass != type) {
type.setRedirect(mClass);
}
return true;
}
}
if (newNameUsed) {
type.setName(name);
}
if (testModuleImports) {
if (resolveAliasFromModule(type)) {
return true;
}
if (module.hasPackageName()) {
// check package this class is defined in. The usage of ConstructedClassWithPackage here
// means, that the module package will not be involved when the
// compiler tries to find an inner class.
ConstructedClassWithPackage tmp = new ConstructedClassWithPackage(module.getPackageName(), name);
if (resolve(tmp, false, false, false)) {
ambiguousClass(type, tmp, name);
type.setRedirect(tmp.redirect());
return true;
}
}
if (!name.contains(".")) {
// check module static imports (for static inner classes)
for (ImportNode importNode : module.getStaticImports().values()) {
if (importNode.getFieldName().equals(name)) {
ClassNode tmp = new ConstructedNestedClass(importNode.getType(), name);
if (resolve(tmp, false, false, true)) {
if ((tmp.getModifiers() & Opcodes.ACC_STATIC) != 0) {
type.setRedirect(tmp.redirect());
return true;
}
}
}
}
// check module node import packages
for (ImportNode importNode : module.getStarImports()) {
String packagePrefix = importNode.getPackageName();
// We limit the inner class lookups here by using ConstructedClassWithPackage.
// This way only the name will change, the packagePrefix will
// not be included in the lookup. The case where the
// packagePrefix is really a class is handled elsewhere.
ConstructedClassWithPackage tmp = new ConstructedClassWithPackage(packagePrefix, name);
if (resolve(tmp, false, false, true)) {
ambiguousClass(type, tmp, name);
type.setRedirect(tmp.redirect());
return true;
}
}
// check for star imports (import static pkg.Outer.*) matching static inner classes
for (ImportNode importNode : module.getStaticStarImports().values()) {
ClassNode tmp = new ConstructedNestedClass(importNode.getType(), name);
if (resolve(tmp, false, false, true)) {
if ((tmp.getModifiers() & Opcodes.ACC_STATIC) != 0) {
ambiguousClass(type, tmp, name);
type.setRedirect(tmp.redirect());
return true;
}
}
}
}
}
return false;
}
Aggregations