
net.jangaroo.jooc.ImplementedMembersAnalyzer Maven / Gradle / Ivy
The newest version!
package net.jangaroo.jooc;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import net.jangaroo.jooc.ast.ClassDeclaration;
import net.jangaroo.jooc.ast.CommaSeparatedList;
import net.jangaroo.jooc.ast.CompilationUnit;
import net.jangaroo.jooc.ast.FunctionDeclaration;
import net.jangaroo.jooc.ast.Ide;
import net.jangaroo.jooc.ast.IdeDeclaration;
import net.jangaroo.jooc.ast.Implements;
import net.jangaroo.jooc.ast.TypedIdeDeclaration;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
/**
* Check if methods defined in interfaces are actually implemented in implementing classes.
*
* Adobe AS3 Docs
*/
class ImplementedMembersAnalyzer {
private Jooc jooc;
private Collection inspected = new HashSet<>();
private Multimap membersByInterfaceQName = LinkedHashMultimap.create();
private Multimap membersByClassQName = LinkedHashMultimap.create();
ImplementedMembersAnalyzer(Jooc jooc) {
this.jooc = jooc;
}
void analyzeImplementedMembers(CompilationUnit compilationUnit) {
IdeDeclaration primaryDeclaration = compilationUnit.getPrimaryDeclaration();
String qName = primaryDeclaration.getQualifiedNameStr();
if (primaryDeclaration instanceof ClassDeclaration && inspected.add(qName)) {
visitClassDeclaration((ClassDeclaration) primaryDeclaration);
}
}
void visitClassDeclaration(ClassDeclaration classDeclaration) {
String qName = classDeclaration.getQualifiedNameStr();
boolean isInterface = classDeclaration.isInterface();
Collection toBeImplemented = new LinkedHashSet<>();
Implements optImplements = classDeclaration.getOptImplements();
if (null != optImplements) {
for (CommaSeparatedList localSuperTypes = optImplements.getSuperTypes(); localSuperTypes != null; localSuperTypes = localSuperTypes.getTail()) {
String superClassQName = localSuperTypes.getHead().getDeclaration().getQualifiedNameStr();
analyzeImplementedMembers(jooc.getCompilationUnit(superClassQName));
Collection superClassMembers = membersByInterfaceQName.get(superClassQName);
if (isInterface) {
// add inherited methods to current methods
membersByInterfaceQName.putAll(qName, superClassMembers);
} else {
toBeImplemented.addAll(superClassMembers);
}
}
}
ClassDeclaration superTypeDeclaration = classDeclaration.getSuperTypeDeclaration();
if (null != superTypeDeclaration) {
String superClassQName = superTypeDeclaration.getQualifiedNameStr();
analyzeImplementedMembers(jooc.getCompilationUnit(superClassQName));
// add inherited methods to current methods
membersByClassQName.putAll(qName, membersByClassQName.get(superClassQName));
}
ClassDeclaration classModel = (ClassDeclaration) jooc.resolveCompilationUnit(qName).getPrimaryDeclaration();
Iterable methodModels = classModel.getMethods();
if (isInterface) {
membersByInterfaceQName.putAll(qName, methodModels);
} else {
FunctionDeclaration constructor = classModel.getConstructor();
Iterable publicNonStaticMethods = Iterables.filter(methodModels, Predicates.and(new Predicate() {
@Override
public boolean apply(@Nullable FunctionDeclaration input) {
//noinspection ConstantConditions
return !input.isStatic() && input.isPublic();
}
}, Predicates.not(Predicates.equalTo(constructor))));
membersByClassQName.putAll(qName, publicNonStaticMethods);
}
if (!isInterface) {
Collection implemented = membersByClassQName.get(qName);
toBeImplemented.addAll(membersByInterfaceQName.get(qName));
toBeImplemented.removeAll(implemented);
if (!toBeImplemented.isEmpty()) {
throw JangarooParser.error(optImplements, "Does not implement " + Iterables.transform(toBeImplemented, new Function() {
@Nullable
@Override
public String apply(@Nullable TypedIdeDeclaration input) {
//noinspection ConstantConditions
if (input instanceof FunctionDeclaration && ((FunctionDeclaration) input).isGetterOrSetter()) {
return ((FunctionDeclaration)input).getSymGetOrSet().getText() + " " + input.getName();
}
return input == null ? null : input.getName();
}
}));
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy