Skip to content

Commit

Permalink
Reduce use of fake anon type from GroovyProjectFacade
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Aug 27, 2018
1 parent d0372b7 commit 97c2d51
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 304 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1164,7 +1164,7 @@ private void createTypeDeclarations(ModuleNode moduleNode) {
allocation.sourceStart = isEnum ? typeDeclaration.sourceStart : typeDeclaration.sourceStart - 4; // approx. offset of "new"
allocation.sourceEnd = typeDeclaration.bodyEnd;
// TODO: allocation.typeArguments = something
allocation.type = typeDeclaration.superclass;
if (!isEnum) allocation.type = typeDeclaration.superclass;
}
} else {
typeDeclarations.add(typeDeclaration);
Expand Down Expand Up @@ -1242,11 +1242,12 @@ private FieldDeclaration[] createFieldDeclarations(ClassNode classNode, boolean
fieldDeclaration.annotations = createAnnotations(fieldNode.getAnnotations());
if (!isEnumField) {
fieldDeclaration.modifiers = getModifiers(fieldNode);
fieldDeclaration.type = createTypeReferenceForClassNode(fieldNode.getType());
fieldDeclaration.initializer = fieldNode.getInitialExpression();
if (fieldNode.isStatic() && fieldNode.isFinal() && fieldNode.getInitialExpression() instanceof ConstantExpression) {
// this needs to be set for static finals to correctly determine constant status
fieldDeclaration.initialization = createConstantExpression((ConstantExpression) fieldNode.getInitialExpression());
}
fieldDeclaration.type = createTypeReferenceForClassNode(fieldNode.getType());

if (anonymousLocations != null && fieldNode.getInitialExpression() != null) {
fieldNode.getInitialExpression().visit(new CodeVisitorSupport() {
Expand All @@ -1260,7 +1261,6 @@ public void visitConstructorCallExpression(ConstructorCallExpression call) {
});
}
}
fieldDeclaration.initializer = fieldNode.getInitialExpression();
fixupSourceLocationsForFieldDeclaration(fieldDeclaration, fieldNode, isEnumField);

fieldDeclarations.add(fieldDeclaration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,27 @@
*/
package org.codehaus.jdt.groovy.model;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.InnerClassNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.expr.DeclarationExpression;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.groovy.core.util.GroovyUtils;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.LocalVariable;
import org.eclipse.jdt.internal.core.ResolvedSourceField;
import org.eclipse.jdt.internal.core.ResolvedSourceMethod;
import org.eclipse.jdt.internal.core.ResolvedSourceType;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.util.Util;

public class GroovyProjectFacade {
Expand All @@ -74,72 +60,24 @@ public IJavaProject getProject() {
return project;
}

/**
* best effort to map a groovy node to a JavaElement
* If the groovy element is not a declaration (eg- an expression or statement)
* returns instead the closest enclosing element that can be converted
* to an IJavaElement
*
* If node is a local variable declaration, then returns a LocalVariable
*/
public IJavaElement groovyNodeToJavaElement(ASTNode node, IFile file) {
ICompilationUnit unit = JavaCore.createCompilationUnitFrom(file);
if (!(unit instanceof GroovyCompilationUnit)) {
// can't go any further, just return the unit instead
Util.log(IStatus.WARNING, "Trying to get a groovy element from a non-groovy file: " + file.getName());
return unit;
}

try {
int start = node.getStart();
IJavaElement elt = unit.getElementAt(start);
if (node instanceof DeclarationExpression) {
String var = ((DeclarationExpression) node).getVariableExpression().getName();
int end = start + var.length() - 1;
String sig = Signature.createTypeSignature(((DeclarationExpression) node).getVariableExpression().getType().getName(), false);

return new LocalVariable((JavaElement) elt, var, start, end, start, end, sig, null, 0, false);
} else {
return elt;
}
} catch (Exception e) {
Util.log(e, "Error converting from Groovy Element to Java Element: " + node.getText());
}
return null;
}

@Deprecated // use org.codehaus.jdt.groovy.model.JavaCoreUtil.findType(String, IJavaElement)
public IType groovyClassToJavaType(ClassNode node) {
if (parent != null && parent.getFullyQualifiedName().equals(node.getName())) {
return parent;
}
try {
ClassNode toLookFor = node;
if (GroovyUtils.isAnonymous(node)) {
toLookFor = node.getOuterClass();
IType enclosing = groovyClassToJavaType(toLookFor);
if (enclosing != null && !enclosing.isBinary()) {
return fakeAnonymousInnerClass(enclosing, (InnerClassNode) node);
} else {
// if the 'enclosing' is binary we may assume this one is also binary,
// so we should just be able to look for it with the type name (including the $ etc.)
return project.findType(node.getName(), (IProgressMonitor) null);
}
}

// GRECLIPSE-800: ensure that inner class nodes are handled properly
String name = toLookFor.getName().replace('$', '.');
IType type = project.findType(name, (IProgressMonitor) null);
if (type != null && toLookFor != node) {
type = type.getType("", 1);
if (!type.exists()) {
type = null;
}
IType type = null;
if (GroovyUtils.isAnonymous(node)) {
type = JavaCoreUtil.findType(node.getOuterClass().getName(), project);
if (type != null && type.exists() && !type.isBinary()) {
type = fakeAnonymousInnerClass(type, (InnerClassNode) node);
} else {
type = null;
}
return type;
} catch (JavaModelException e) {
Util.log(e, "Error converting from Groovy Element to Java Element: " + node.getName());
return null;
}
if (type == null) {
type = JavaCoreUtil.findType(node.getName(), project);
}
return type;
}

private IType fakeAnonymousInnerClass(IType outer, final InnerClassNode inner) {
Expand Down Expand Up @@ -238,37 +176,6 @@ public Object getElementInfo() throws JavaModelException {
};
}

GroovyCompilationUnit groovyModuleToCompilationUnit(ModuleNode node) {
List<ClassNode> classes = node.getClasses();
ClassNode classNode = !classes.isEmpty() ? (ClassNode) classes.get(0) : null;
if (classNode != null) {
IType type = groovyClassToJavaType(classNode);
if (type instanceof SourceType) {
return (GroovyCompilationUnit) type.getCompilationUnit();
}
}
Util.log(IStatus.WARNING, "Trying to get GroovyCompilationUnit for non-groovy module: " + node.getDescription());
return null;
}

/**
* If this fully qualified name is in a groovy file, then return the
* ClassNode.
*
* If this is not a groovy file, then return null
*/
public ClassNode getClassNodeForName(String name) {
try {
IType type = project.findType(name, (IProgressMonitor) null);
if (type instanceof SourceType) {
return javaTypeToGroovyClass(type);
}
} catch (JavaModelException e) {
Util.log(e);
}
return null;
}

private Parameter[] getParametersForTypes(String[] signatures) {
int n = signatures.length;
Parameter[] parameters = new Parameter[n];
Expand All @@ -278,60 +185,7 @@ private Parameter[] getParametersForTypes(String[] signatures) {
return parameters;
}

private static ClassNode javaTypeToGroovyClass(String signature) {
int dims = Signature.getArrayCount(signature); // TODO: handle generics types
String type = Signature.toString(Signature.getTypeErasure(signature.substring(dims)));

ClassNode node = ClassHelper.make(type);
while (dims-- > 0) {
node = node.makeArray();
}
return node;
}

private static ClassNode javaTypeToGroovyClass(IType type) {
ICompilationUnit unit = type.getCompilationUnit();
if (unit instanceof GroovyCompilationUnit) {
ModuleNode module = ((GroovyCompilationUnit) unit).getModuleNode();
List<ClassNode> classes = module.getClasses();
for (ClassNode classNode : classes) {
if (classNode.getNameWithoutPackage().equals(type.getElementName())) {
return classNode;
}
}
}
return null;
}

public List<IType> findAllRunnableTypes() throws JavaModelException {
final List<IType> results = new ArrayList<>();
IPackageFragmentRoot[] roots = project.getAllPackageFragmentRoots();
for (IPackageFragmentRoot root : roots) {
if (!root.isReadOnly()) {
IJavaElement[] children = root.getChildren();
for (IJavaElement child : children) {
if (child.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
ICompilationUnit[] units = ((IPackageFragment) child).getCompilationUnits();
for (ICompilationUnit unit : units) {
results.addAll(findAllRunnableTypes(unit));
}
}
}
}
}
return results;
}

public static List<IType> findAllRunnableTypes(ICompilationUnit unit) throws JavaModelException {
List<IType> results = new LinkedList<>();
IType[] types = unit.getAllTypes();
for (IType type : types) {
if (hasRunnableMain(type)) {
results.add(type);
}
}
return results;
}
//--------------------------------------------------------------------------

public static boolean hasRunnableMain(IType type) {
try {
Expand Down Expand Up @@ -369,51 +223,35 @@ private static boolean hasAppropriateArrayArgsForMain(final String[] params) {
return (name.equals(typeName)) && (qual == null || qual.isEmpty() || "java.lang".equals(qual));
}

public List<IType> findAllScripts() throws JavaModelException {
final List<IType> results = new ArrayList<>();
IPackageFragmentRoot[] roots = project.getAllPackageFragmentRoots();
for (IPackageFragmentRoot root : roots) {
if (!root.isReadOnly()) {
IJavaElement[] children = root.getChildren();
for (IJavaElement child : children) {
if (child.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
ICompilationUnit[] units = ((IPackageFragment) child).getCompilationUnits();
for (ICompilationUnit unit : units) {
if (unit instanceof GroovyCompilationUnit) {
for (IType type : unit.getTypes()) {
if (isGroovyScript(type)) {
results.add(type);
}
}
}
}
}
}
}
}
return results;
}

public boolean isGroovyScript(IType type) {
public static boolean isGroovyScript(IType type) {
ClassNode node = javaTypeToGroovyClass(type);
if (node != null) {
return node.isScript();
}
return false;
}

public boolean isGroovyScript(ICompilationUnit unit) {
private static ClassNode javaTypeToGroovyClass(IType type) {
ICompilationUnit unit = type.getCompilationUnit();
if (unit instanceof GroovyCompilationUnit) {
GroovyCompilationUnit gunit = (GroovyCompilationUnit) unit;
ModuleNode module = gunit.getModuleNode();
if (module != null) {
for (ClassNode clazz : (Iterable<ClassNode>) module.getClasses()) {
if (clazz.isScript()) {
return true;
}
ModuleNode module = ((GroovyCompilationUnit) unit).getModuleNode();
for (ClassNode classNode : module.getClasses()) {
if (classNode.getNameWithoutPackage().equals(type.getElementName())) {
return classNode;
}
}
}
return false;
return null;
}

private static ClassNode javaTypeToGroovyClass(String signature) {
int dims = Signature.getArrayCount(signature); // TODO: handle generics types
String type = Signature.toString(Signature.getTypeErasure(signature.substring(dims)));

ClassNode node = ClassHelper.make(type);
while (dims-- > 0) {
node = node.makeArray();
}
return node;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2009-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.jdt.groovy.model;

import org.codehaus.groovy.ast.ConstructorNode;
import org.codehaus.groovy.ast.MethodNode;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IJavaElement;
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.groovy.core.util.GroovyUtils;
import org.eclipse.jdt.internal.core.util.Util;

/**
* @see org.eclipse.jdt.internal.corext.util.JavaModelUtil
*/
public class JavaCoreUtil {

private JavaCoreUtil() {}

public static IMethod findMethod(MethodNode methodNode, IType declaringType) {
try {
char[] methodName = methodNode.getName().toCharArray();
String[] paramTypes = GroovyUtils.getParameterTypeSignatures(methodNode, declaringType.isBinary());
return Util.findMethod(declaringType, methodName, paramTypes, methodNode instanceof ConstructorNode);
} catch (JavaModelException e) {
Util.log(e);
return null;
}
}

public static IMethod findMethod(MethodNode methodNode, IJavaElement referenceContext) {
IType declaringType = findType(methodNode.getDeclaringClass().getName(), referenceContext);
return findMethod(methodNode, declaringType);
}

public static IType findType(String fullyQualifiedName, IJavaElement referenceContext) {
try {
IJavaProject project = referenceContext.getJavaProject();
return project.findType(fullyQualifiedName.replace('$', '.'), (IProgressMonitor) null);
} catch (JavaModelException e) {
Util.log(e);
return null;
}
}
}
Loading

0 comments on commit 97c2d51

Please sign in to comment.