/*******************************************************************************
* Copyright (c) 2011 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.definitions;
import static dtool.engine.analysis.DeeLanguageIntrinsics.D2_063_intrinsics;
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.context.ISemanticContext;
import melnorme.lang.tooling.engine.PickedElement;
import melnorme.lang.tooling.engine.resolver.TypeSemantics;
import melnorme.lang.tooling.engine.scoping.CommonScopeLookup;
import melnorme.lang.tooling.engine.scoping.IScopeElement;
import melnorme.lang.tooling.engine.scoping.NamedElementsScope;
import melnorme.lang.tooling.engine.scoping.ScopeTraverser;
import melnorme.lang.tooling.symbols.IConcreteNamedElement;
import melnorme.lang.tooling.symbols.ITypeNamedElement;
import melnorme.utilbox.collections.ArrayView;
import dtool.ast.declarations.DeclBlock;
import dtool.ast.expressions.Expression;
import dtool.ast.statements.IStatement;
import dtool.parser.common.Token;
/**
* A definition of a aggregate.
*/
public abstract class DefinitionAggregate extends CommonDefinition
implements IStatement, IScopeElement, ITemplatableElement, IConcreteNamedElement, ITypeNamedElement
{
public interface IAggregateBody extends IASTNode {
}
public final NodeVector<ITemplateParameter> tplParams;
public final Expression tplConstraint;
public final IAggregateBody aggrBody;
public DefinitionAggregate(Token[] comments, DefSymbol defId, NodeVector<ITemplateParameter> tplParams,
Expression tplConstraint, IAggregateBody aggrBody) {
super(comments, defId);
this.tplParams = parentize(tplParams);
this.tplConstraint = parentize(tplConstraint);
this.aggrBody = parentize(aggrBody);
}
protected void acceptNodeChildren(IASTVisitor visitor) {
acceptVisitor(visitor, defName);
acceptVisitor(visitor, tplParams);
acceptVisitor(visitor, tplConstraint);
acceptVisitor(visitor, aggrBody);
}
public void aggregateToStringAsCode(ASTCodePrinter cp, String keyword, boolean printDecls) {
cp.append(keyword);
cp.append(defName, " ");
cp.appendList("(", tplParams, ",", ") ");
DefinitionTemplate.tplConstraintToStringAsCode(cp, tplConstraint);
if(printDecls) {
cp.append(aggrBody, "\n");
}
}
@Override
public boolean isTemplated() {
return tplParams != null;
}
@Override
public NodeVector<ITemplateParameter> getTemplateParameters() {
return tplParams;
}
public ArrayView<ASTNode> getAggregateMembers() {
return (aggrBody instanceof DeclBlock) ?
((DeclBlock) aggrBody).nodes :
ArrayView.<ASTNode>createFrom();
}
/* ----------------- ----------------- */
@Override
public AggregateSemantics getSemantics(ISemanticContext parentContext) {
return (AggregateSemantics) super.getSemantics(parentContext);
}
@Override
protected AggregateSemantics doCreateSemantics(PickedElement<?> pickedElement) {
return new AggregateSemantics(this, pickedElement,
new MembersScopeElement(getAggregateMembers()),
new NamedElementsScope(D2_063_intrinsics.createCommonProperties(this)));
}
public class AggregateSemantics extends TypeSemantics {
protected final NamedElementsScope commonTypeScope;
public AggregateSemantics(DefinitionAggregate typeElement, PickedElement<?> pickedElement,
IScopeElement membersScope, NamedElementsScope commonTypeScope) {
super(typeElement, pickedElement, membersScope);
this.commonTypeScope = commonTypeScope;
}
@Override
public void resolveSearchInMembersScope(CommonScopeLookup search) {
search.evaluateScope(getMembersScope());
search.evaluateScope(commonTypeScope);
}
}
/* ----------------- ----------------- */
@Override
public ScopeTraverser getScopeTraverser() {
return new ScopeTraverser(tplParams, false);
}
}