/******************************************************************************* * Copyright (c) 2013 Bruno Medeiros and other Contributors. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Bruno Medeiros - initial API and implementation *******************************************************************************/ package dtool.ast.declarations; import static dtool.util.NewUtils.assertCast; import static melnorme.utilbox.core.Assert.AssertNamespace.assertFail; import melnorme.lang.tooling.ast.CommonASTNode; import melnorme.lang.tooling.ast.IASTNode; import melnorme.lang.tooling.ast.IASTVisitor; import melnorme.lang.tooling.ast.util.ASTCodePrinter; import melnorme.lang.tooling.ast.util.NodeVector; import melnorme.lang.tooling.ast_actual.ASTNode; import melnorme.lang.tooling.ast_actual.ASTNodeTypes; import melnorme.lang.tooling.context.ISemanticContext; import melnorme.lang.tooling.engine.scoping.CommonScopeLookup.ScopeNameResolution; import melnorme.lang.tooling.engine.scoping.INonScopedContainer; import melnorme.lang.tooling.symbols.INamedElement; import melnorme.utilbox.core.DevelopmentCodeMarkers; import dtool.ast.declarations.DeclarationImport.IImportFragment; import dtool.ast.references.RefImportSelection; import dtool.ast.references.RefModule; public class ImportSelective extends ASTNode implements INonScopedContainer, IImportFragment { public static interface IImportSelectiveSelection extends IASTNode { //String getTargetName(); } public final IImportFragment fragment; public final NodeVector<IImportSelectiveSelection> impSelFrags; public ImportSelective(IImportFragment fragment, NodeVector<IImportSelectiveSelection> frags) { this.fragment = parentize(fragment); this.impSelFrags = parentizeFrags(frags); } @Override public ASTNodeTypes getNodeType() { return ASTNodeTypes.IMPORT_SELECTIVE; } @Override protected DeclarationImport getParent_Concrete() { return assertCast(parent, DeclarationImport.class); } public DeclarationImport getDeclarationImport() { return getParent_Concrete(); } public NodeVector<IImportSelectiveSelection> parentizeFrags(NodeVector<IImportSelectiveSelection> frags) { if (frags != null) { for (IImportSelectiveSelection selection : frags) { ((ASTNode) selection).setParent(this); if (selection instanceof ImportSelectiveAlias) { ((ImportSelectiveAlias) selection).target.impSel = this; } else if (selection instanceof RefImportSelection) { ((RefImportSelection) selection).impSel = this; } else { assertFail(); } } } return frags; } @Override public RefModule getModuleRef() { return fragment.getModuleRef(); } @Override public void visitChildren(IASTVisitor visitor) { acceptVisitor(visitor, fragment); acceptVisitor(visitor, impSelFrags); } @Override protected CommonASTNode doCloneTree() { return new ImportSelective(clone(fragment), clone(impSelFrags)); } @Override public Iterable<? extends IASTNode> getMembersIterable() { return impSelFrags; } @Override public void toStringAsCode(ASTCodePrinter cp) { cp.append(fragment, " : "); cp.appendList(impSelFrags, ", "); } /* ----------------- ----------------- */ @Override public void evaluateImportsScopeContribution(ScopeNameResolution scopeRes, boolean isSecondaryScope) { if(isSecondaryScope) { return; } if(fragment instanceof ImportContent) { if(DevelopmentCodeMarkers.DISABLED_FUNCTIONALITY) { // DMD doesn't work like this. ImportContent importContent = (ImportContent) fragment; ImportContent.resolveStaticImport(scopeRes, importContent.moduleRef); } } else if(fragment instanceof ImportAlias){ // TODO: blah, blah, stupid feature anyways } resolveScopeElements(this, scopeRes); } public static void resolveScopeElements(ImportSelective impSelective, ScopeNameResolution scopeRes) { ISemanticContext context = scopeRes.getContext(); INamedElement targetModule = ImportContent.resolveTargetModule(context, impSelective); if (targetModule == null) return; for(IImportSelectiveSelection impSelFrag: impSelective.impSelFrags) { if(impSelFrag instanceof RefImportSelection) { RefImportSelection refImportSelection = (RefImportSelection) impSelFrag; String name = refImportSelection.getDenulledIdentifier(); // Do pre-emptive matching if(!scopeRes.getLookup().matchesName(name)) { continue; } INamedElement selectedElement = refImportSelection.resolveTargetElement(context); scopeRes.visitNamedElement(selectedElement); } } } }