package com.redhat.ceylon.eclipse.core.model; import java.util.Stack; import com.redhat.ceylon.model.typechecker.model.Declaration; import com.redhat.ceylon.model.typechecker.model.Package; import com.redhat.ceylon.model.typechecker.model.Scope; import com.redhat.ceylon.model.typechecker.model.Value; import com.redhat.ceylon.eclipse.core.typechecker.ExternalPhasedUnit; import com.redhat.ceylon.eclipse.util.SingleSourceUnitPackage; /* * Used when the external declarations come from a source archive that doesn't have any binary version, * or the binary car isn't taken in account (current behavior) => this unit will contain declarations * */ public class ExternalSourceFile extends SourceFile { public ExternalSourceFile(ExternalPhasedUnit phasedUnit) { super(phasedUnit); } @Override public ExternalPhasedUnit getPhasedUnit() { return (ExternalPhasedUnit) super.getPhasedUnit(); } public boolean isBinaryDeclarationSource() { JDTModule module = getModule(); return module.isCeylonBinaryArchive() && (getPackage() instanceof SingleSourceUnitPackage); } public Declaration retrieveBinaryDeclaration(Declaration sourceDeclaration) { if (! this.equals(sourceDeclaration.getUnit())) { return null; } Declaration binaryDeclaration = null; if (isBinaryDeclarationSource()) { SingleSourceUnitPackage sourceUnitPackage = (SingleSourceUnitPackage) getPackage(); Package binaryPackage = sourceUnitPackage.getModelPackage(); Stack<Declaration> ancestors = new Stack<>(); Scope container = sourceDeclaration.getContainer(); while (container instanceof Declaration) { Declaration ancestor = (Declaration) container; ancestors.push(ancestor); container = ancestor.getContainer(); } if (container.equals(sourceUnitPackage)) { Scope curentBinaryScope = binaryPackage; while (! ancestors.isEmpty()) { Declaration binaryAncestor = curentBinaryScope.getDirectMember(ancestors.pop().getName(), null, false); if (binaryAncestor instanceof Value) { binaryAncestor = ((Value) binaryAncestor).getTypeDeclaration(); } if (binaryAncestor instanceof Scope) { curentBinaryScope = (Scope) binaryAncestor; } else { break; } } if (curentBinaryScope != null) { binaryDeclaration = curentBinaryScope.getDirectMember(sourceDeclaration.getName(), null, false); } } } return binaryDeclaration; } }