/*******************************************************************************
* Copyright (c) 2014 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.engine.analysis.templates;
import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull;
import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue;
import static melnorme.utilbox.core.Assert.AssertNamespace.assertUnreachable;
import melnorme.lang.tooling.ast.CommonASTNode;
import melnorme.lang.tooling.ast.IASTVisitor;
import melnorme.lang.tooling.ast.INamedElementNode;
import melnorme.lang.tooling.ast.util.ASTCodePrinter;
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.IScopeElement;
import melnorme.lang.tooling.engine.scoping.ScopeTraverser;
import melnorme.lang.tooling.symbols.INamedElement;
import melnorme.utilbox.collections.Indexable;
import dtool.ast.definitions.DefUnit;
import dtool.ast.definitions.ITemplatableElement;
import dtool.ast.references.RefTemplateInstance;
public class TemplateInstance extends ASTNode implements IScopeElement {
public final RefTemplateInstance templateRef;
public final ISemanticContext refContext;
public final ITemplatableElement templateDef;
public final Indexable<INamedElementNode> tplArguments;
public final DefUnit instantiatedElement;
public TemplateInstance(RefTemplateInstance templateRef, ISemanticContext refContext,
ITemplatableElement templateDef, Indexable<INamedElementNode> tplArguments) {
super();
this.templateRef = assertNotNull(templateRef);
this.refContext = refContext;
this.templateDef = assertNotNull(templateDef);
assertTrue(templateDef instanceof ASTNode);
this.tplArguments = parentize(assertNotNull(tplArguments));
assertTrue(tplArguments.size() == templateDef.getTemplateParameters().size());
for (INamedElementNode _node : tplArguments) {
ASTNode node = (ASTNode) _node;
node.setSourceRange(templateDef.getStartPos(), 0);
node.setParsedStatus();
}
this.instantiatedElement = parentize(templateDef.cloneTemplateElement(templateRef));
setParsedFromOther(this, templateDef.asNode());
setElementReady();
setParent(templateDef.asNode().getLexicalParent());
}
@Override
public void visitChildren(IASTVisitor visitor) {
acceptVisitor(visitor, tplArguments);
acceptVisitor(visitor, instantiatedElement);
}
@Override
protected CommonASTNode doCloneTree() {
// Because this is not actually a source element (an element that is parser),
// this method is not reachable.
throw assertUnreachable();
}
@Override
public ASTNodeTypes getNodeType() {
return ASTNodeTypes.DEFINITION_TEMPLATE;
}
@Override
public void toStringAsCode(ASTCodePrinter cp) {
cp.appendList("@{", tplArguments, " ", "}");
cp.append(instantiatedElement);
}
/* ----------------- ----------------- */
@Override
public INamedElement getContainingModuleNamespace() {
return templateDef.asNode().getContainingModuleNamespace();
}
/* ----------------- ----------------- */
@Override
public ScopeTraverser getScopeTraverser() {
return new ScopeTraverser(tplArguments, true);
}
}