/*
* Copyright 2017-present Facebook, Inc.
*
* 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.facebook.buck.jvm.java.abi.source;
import com.sun.source.tree.ModifiersTree;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementVisitor;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
/**
* An implementation of {@link TypeElement} that uses only the information available from one or
* more {@link com.sun.source.tree.CompilationUnitTree}s. This results in an incomplete
* implementation; see documentation for individual methods and {@link
* com.facebook.buck.jvm.java.abi.source} for more information.
*/
class TreeBackedPackageElement extends TreeBackedElement implements PackageElement {
private final PackageElement javacPackage;
private final StandalonePackageType typeMirror;
private boolean resolved = false;
public TreeBackedPackageElement(PackageElement javacPackage, TreeBackedElementResolver resolver) {
super(javacPackage, null, null, resolver);
this.javacPackage = javacPackage;
typeMirror = resolver.createType(this);
}
@Override
public List<? extends Element> getEnclosedElements() {
resolve();
return super.getEnclosedElements();
}
private void resolve() {
if (resolved) {
return;
}
if (javacPackage != null) {
// Java allows packages to be split across modules, so once we've found all the tree-backed
// elements (i.e., elements from the current module), we fill in the ones from modules on
// the classpath.
List<? extends Element> treeBackedEnclosedElements = super.getEnclosedElements();
Set<Name> enclosedElementNames =
treeBackedEnclosedElements
.stream()
.map(Element::getSimpleName)
.collect(Collectors.toSet());
for (Element element : javacPackage.getEnclosedElements()) {
if (enclosedElementNames.contains(element.getSimpleName())) {
// This was already added when parsing the tree-backed elements
continue;
}
addEnclosedElement(element);
}
}
resolved = true;
}
@Override
public Name getQualifiedName() {
return javacPackage.getQualifiedName();
}
@Override
public boolean isUnnamed() {
return javacPackage.isUnnamed();
}
@Override
public StandalonePackageType asType() {
return typeMirror;
}
@Override
protected ModifiersTree getModifiersTree() {
throw new UnsupportedOperationException();
}
@Override
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
return v.visitPackage(this, p);
}
}