Skip to content

Commit

Permalink
Adds CommonTypeDeclaration to provide a common supertype for Abstract…
Browse files Browse the repository at this point in the history
…TypeDeclaration and AnonymousClassDeclaration.

	Change on 2016/10/05 by kstanger <kstanger@google.com>

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=135251122
  • Loading branch information
kstanger authored and tomball committed Oct 7, 2016
1 parent 033707e commit 9e294e1
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 54 deletions.
1 change: 1 addition & 0 deletions translator/Makefile
Expand Up @@ -79,6 +79,7 @@ JAVA_SOURCES = \
ast/ClassInstanceCreation.java \ ast/ClassInstanceCreation.java \
ast/CommaExpression.java \ ast/CommaExpression.java \
ast/Comment.java \ ast/Comment.java \
ast/CommonTypeDeclaration.java \
ast/CompilationUnit.java \ ast/CompilationUnit.java \
ast/ConditionalExpression.java \ ast/ConditionalExpression.java \
ast/ConstructorInvocation.java \ ast/ConstructorInvocation.java \
Expand Down
Expand Up @@ -23,7 +23,8 @@
/** /**
* Superclass node for classes, enums and annotation declarations. * Superclass node for classes, enums and annotation declarations.
*/ */
public abstract class AbstractTypeDeclaration extends BodyDeclaration { public abstract class AbstractTypeDeclaration extends BodyDeclaration
implements CommonTypeDeclaration {


private TypeElement typeElement = null; private TypeElement typeElement = null;
protected final ChildLink<SimpleName> name = ChildLink.create(SimpleName.class, this); protected final ChildLink<SimpleName> name = ChildLink.create(SimpleName.class, this);
Expand Down Expand Up @@ -64,6 +65,7 @@ public void setTypeBinding(ITypeBinding typeBinding) {
this.typeElement = BindingConverter.getTypeElement(typeBinding); this.typeElement = BindingConverter.getTypeElement(typeBinding);
} }


@Override
public TypeElement getTypeElement() { public TypeElement getTypeElement() {
return typeElement; return typeElement;
} }
Expand All @@ -82,6 +84,7 @@ public AbstractTypeDeclaration setName(SimpleName newName) {
return this; return this;
} }


@Override
public List<BodyDeclaration> getBodyDeclarations() { public List<BodyDeclaration> getBodyDeclarations() {
return bodyDeclarations; return bodyDeclarations;
} }
Expand Down
Expand Up @@ -23,7 +23,7 @@
* Anonymous class declaration node. Must be the child of a * Anonymous class declaration node. Must be the child of a
* ClassInstanceCreation node. * ClassInstanceCreation node.
*/ */
public final class AnonymousClassDeclaration extends TreeNode { public final class AnonymousClassDeclaration extends TreeNode implements CommonTypeDeclaration {


private TypeElement element = null; private TypeElement element = null;
private final ChildList<BodyDeclaration> bodyDeclarations = private final ChildList<BodyDeclaration> bodyDeclarations =
Expand All @@ -47,6 +47,7 @@ public ITypeBinding getTypeBinding() {
return (ITypeBinding) BindingConverter.unwrapElement(element); return (ITypeBinding) BindingConverter.unwrapElement(element);
} }


@Override
public TypeElement getTypeElement() { public TypeElement getTypeElement() {
return element; return element;
} }
Expand All @@ -56,6 +57,7 @@ public AnonymousClassDeclaration setTypeElement(TypeElement newElement) {
return this; return this;
} }


@Override
public List<BodyDeclaration> getBodyDeclarations() { public List<BodyDeclaration> getBodyDeclarations() {
return bodyDeclarations; return bodyDeclarations;
} }
Expand Down
@@ -0,0 +1,34 @@
/*
* 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 com.google.devtools.j2objc.ast;

import java.util.List;
import javax.lang.model.element.TypeElement;

/**
* A common supertype for AbstractTypeDeclaration and AnonymousClassDeclaration.
*/
public interface CommonTypeDeclaration {

TypeElement getTypeElement();

List<BodyDeclaration> getBodyDeclarations();

// CommonTypeDeclaration can not be made a subtype of TreeNode because TreeNode is not an
// interface.
default TreeNode asNode() {
return (TreeNode) this;
}
}
Expand Up @@ -105,7 +105,7 @@ public static Annotation getAnnotation(Class<?> annotationClass, List<Annotation
return null; return null;
} }


public static <T extends TreeNode> T getNearestAncestorWithType(Class<T> type, TreeNode node) { public static <T> T getNearestAncestorWithType(Class<T> type, TreeNode node) {
while (node != null) { while (node != null) {
if (type.isInstance(node)) { if (type.isInstance(node)) {
return type.cast(node); return type.cast(node);
Expand All @@ -115,10 +115,9 @@ public static <T extends TreeNode> T getNearestAncestorWithType(Class<T> type, T
return null; return null;
} }


public static TreeNode getNearestAncestorWithTypeOneOf(List<Class<? extends TreeNode>> types, public static TreeNode getNearestAncestorWithTypeOneOf(List<Class<?>> types, TreeNode node) {
TreeNode node) {
while (node != null) { while (node != null) {
for (Class<? extends TreeNode> c : types) { for (Class<?> c : types) {
if (c.isInstance(node)) { if (c.isInstance(node)) {
return node; return node;
} }
Expand Down Expand Up @@ -203,19 +202,15 @@ public Iterator<VariableDeclarationFragment> iterator() {
}; };
} }


public static Iterable<MethodDeclaration> getMethodDeclarations(AbstractTypeDeclaration node) { public static Iterable<MethodDeclaration> getMethodDeclarations(CommonTypeDeclaration node) {
return getMethodDeclarations(node.getBodyDeclarations());
}

public static Iterable<MethodDeclaration> getMethodDeclarations(AnonymousClassDeclaration node) {
return getMethodDeclarations(node.getBodyDeclarations()); return getMethodDeclarations(node.getBodyDeclarations());
} }


private static Iterable<MethodDeclaration> getMethodDeclarations(List<BodyDeclaration> nodes) { private static Iterable<MethodDeclaration> getMethodDeclarations(List<BodyDeclaration> nodes) {
return Iterables.filter(nodes, MethodDeclaration.class); return Iterables.filter(nodes, MethodDeclaration.class);
} }


public static List<MethodDeclaration> getMethodDeclarationsList(AbstractTypeDeclaration node) { public static List<MethodDeclaration> getMethodDeclarationsList(CommonTypeDeclaration node) {
return Lists.newArrayList(getMethodDeclarations(node)); return Lists.newArrayList(getMethodDeclarations(node));
} }


Expand All @@ -224,19 +219,9 @@ public static Iterable<FunctionDeclaration> getFunctionDeclarations(
return Iterables.filter(node.getBodyDeclarations(), FunctionDeclaration.class); return Iterables.filter(node.getBodyDeclarations(), FunctionDeclaration.class);
} }


public static List<BodyDeclaration> getBodyDeclarations(TreeNode node) {
if (node instanceof AbstractTypeDeclaration) {
return ((AbstractTypeDeclaration) node).getBodyDeclarations();
} else if (node instanceof AnonymousClassDeclaration) {
return ((AnonymousClassDeclaration) node).getBodyDeclarations();
} else {
throw new AssertionError(
"node type does not contains body declarations: " + node.getClass().getSimpleName());
}
}

public static List<BodyDeclaration> asDeclarationSublist(BodyDeclaration node) { public static List<BodyDeclaration> asDeclarationSublist(BodyDeclaration node) {
List<BodyDeclaration> declarations = getBodyDeclarations(node.getParent()); List<BodyDeclaration> declarations =
((CommonTypeDeclaration) node.getParent()).getBodyDeclarations();
int index = declarations.indexOf(node); int index = declarations.indexOf(node);
assert index != -1; assert index != -1;
return declarations.subList(index, index + 1); return declarations.subList(index, index + 1);
Expand All @@ -246,10 +231,8 @@ public static List<BodyDeclaration> asDeclarationSublist(BodyDeclaration node) {
* Gets the element that is declared by this node. * Gets the element that is declared by this node.
*/ */
public static Element getDeclaredElement(TreeNode node) { public static Element getDeclaredElement(TreeNode node) {
if (node instanceof AnonymousClassDeclaration) { if (node instanceof CommonTypeDeclaration) {
return ((AnonymousClassDeclaration) node).getTypeElement(); return ((CommonTypeDeclaration) node).getTypeElement();
} else if (node instanceof AbstractTypeDeclaration) {
return ((AbstractTypeDeclaration) node).getTypeElement();
} else if (node instanceof MethodDeclaration) { } else if (node instanceof MethodDeclaration) {
return ((MethodDeclaration) node).getExecutableElement(); return ((MethodDeclaration) node).getExecutableElement();
} else if (node instanceof VariableDeclaration) { } else if (node instanceof VariableDeclaration) {
Expand Down Expand Up @@ -309,40 +292,29 @@ public static ExecutableElement getExecutableElement(Expression node) {
} }
} }


private static final List<Class<? extends TreeNode>> TYPE_NODE_BASE_CLASSES = public static CommonTypeDeclaration getEnclosingType(TreeNode node) {
ImmutableList.of(AbstractTypeDeclaration.class, AnonymousClassDeclaration.class); return getNearestAncestorWithType(CommonTypeDeclaration.class, node);

public static TreeNode getEnclosingType(TreeNode node) {
return getNearestAncestorWithTypeOneOf(TYPE_NODE_BASE_CLASSES, node);
} }


public static ITypeBinding getEnclosingTypeBinding(TreeNode node) { public static ITypeBinding getEnclosingTypeBinding(TreeNode node) {
return BindingConverter.unwrapTypeElement(getEnclosingTypeElement(node)); return BindingConverter.unwrapTypeElement(getEnclosingTypeElement(node));
} }


public static TypeElement getEnclosingTypeElement(TreeNode node) { public static TypeElement getEnclosingTypeElement(TreeNode node) {
TreeNode enclosingType = getEnclosingType(node); return getEnclosingType(node).getTypeElement();
if (enclosingType instanceof AbstractTypeDeclaration) {
return ((AbstractTypeDeclaration) enclosingType).getTypeElement();
} else if (enclosingType instanceof AnonymousClassDeclaration) {
return ((AnonymousClassDeclaration) enclosingType).getTypeElement();
} else {
return null;
}
} }


public static List<BodyDeclaration> getEnclosingTypeBodyDeclarations(TreeNode node) { public static List<BodyDeclaration> getEnclosingTypeBodyDeclarations(TreeNode node) {
return getBodyDeclarations(getEnclosingType(node)); return getEnclosingType(node).getBodyDeclarations();
} }


public static IMethodBinding getEnclosingMethodBinding(TreeNode node) { public static IMethodBinding getEnclosingMethodBinding(TreeNode node) {
MethodDeclaration enclosingMethod = getNearestAncestorWithType(MethodDeclaration.class, node); MethodDeclaration enclosingMethod = getNearestAncestorWithType(MethodDeclaration.class, node);
return enclosingMethod == null ? null : enclosingMethod.getMethodBinding(); return enclosingMethod == null ? null : enclosingMethod.getMethodBinding();
} }


private static final List<Class<? extends TreeNode>> NODE_TYPES_WITH_ELEMENTS = ImmutableList.of( private static final List<Class<?>> NODE_TYPES_WITH_ELEMENTS = ImmutableList.of(
AbstractTypeDeclaration.class, AnonymousClassDeclaration.class, MethodDeclaration.class, CommonTypeDeclaration.class, MethodDeclaration.class, VariableDeclaration.class);
VariableDeclaration.class);


public static Element getEnclosingElement(TreeNode node) { public static Element getEnclosingElement(TreeNode node) {
return getDeclaredElement(getNearestAncestorWithTypeOneOf(NODE_TYPES_WITH_ELEMENTS, node)); return getDeclaredElement(getNearestAncestorWithTypeOneOf(NODE_TYPES_WITH_ELEMENTS, node));
Expand Down
Expand Up @@ -15,6 +15,7 @@
package com.google.devtools.j2objc.translate; package com.google.devtools.j2objc.translate;


import com.google.devtools.j2objc.ast.ClassInstanceCreation; import com.google.devtools.j2objc.ast.ClassInstanceCreation;
import com.google.devtools.j2objc.ast.CommonTypeDeclaration;
import com.google.devtools.j2objc.ast.Expression; import com.google.devtools.j2objc.ast.Expression;
import com.google.devtools.j2objc.ast.MethodInvocation; import com.google.devtools.j2objc.ast.MethodInvocation;
import com.google.devtools.j2objc.ast.Name; import com.google.devtools.j2objc.ast.Name;
Expand Down Expand Up @@ -134,9 +135,9 @@ public boolean visit(ThisExpression node) {


@Override @Override
public void endVisit(SuperConstructorInvocation node) { public void endVisit(SuperConstructorInvocation node) {
TreeNode typeNode = TreeUtil.getEnclosingType(node); CommonTypeDeclaration typeDecl = TreeUtil.getEnclosingType(node);
TypeElement superType = ElementUtil.getSuperclass( TypeElement superType = ElementUtil.getSuperclass(typeDecl.getTypeElement());
(TypeElement) TreeUtil.getDeclaredElement(typeNode)); TreeNode typeNode = typeDecl.asNode();
List<Expression> args = node.getArguments().subList(0, 0); List<Expression> args = node.getArguments().subList(0, 0);
List<TypeMirror> parameterTypes = new ArrayList<>(); List<TypeMirror> parameterTypes = new ArrayList<>();


Expand Down
Expand Up @@ -254,16 +254,12 @@ public void endVisit(FieldDeclaration node) {
LinkedListMultimap<Integer, VariableDeclarationFragment> newDeclarations = LinkedListMultimap<Integer, VariableDeclarationFragment> newDeclarations =
rewriteExtraDimensions(node.getType(), node.getFragments()); rewriteExtraDimensions(node.getType(), node.getFragments());
if (newDeclarations != null) { if (newDeclarations != null) {
List<BodyDeclaration> bodyDecls = TreeUtil.getBodyDeclarations(node.getParent()); List<BodyDeclaration> bodyDecls = TreeUtil.asDeclarationSublist(node);
int location = 0;
while (location < bodyDecls.size() && !node.equals(bodyDecls.get(location))) {
location++;
}
for (Integer dimensions : newDeclarations.keySet()) { for (Integer dimensions : newDeclarations.keySet()) {
List<VariableDeclarationFragment> fragments = newDeclarations.get(dimensions); List<VariableDeclarationFragment> fragments = newDeclarations.get(dimensions);
FieldDeclaration newDecl = new FieldDeclaration(fragments.get(0)); FieldDeclaration newDecl = new FieldDeclaration(fragments.get(0));
newDecl.getFragments().addAll(fragments.subList(1, fragments.size())); newDecl.getFragments().addAll(fragments.subList(1, fragments.size()));
bodyDecls.add(++location, newDecl); bodyDecls.add(newDecl);
} }
} }
} }
Expand Down

0 comments on commit 9e294e1

Please sign in to comment.