blob: 6c8f545f54dafeca5e5b9317380f88c58ec97528 [file] [log] [blame]
package org.eclipse.cdt.internal.ui.compare;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.util.Stack;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.ast.ASTClassKind;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTField;
import org.eclipse.cdt.core.parser.ast.IASTFunction;
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
import org.eclipse.cdt.core.parser.ast.IASTMacro;
import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation;
import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.jface.text.IDocument;
/**
*
*/
public class CParseTreeBuilder extends SourceElementRequestorAdapter {
private Stack fStack = new Stack();
private IDocument fDocument;
/**
* Syntax Error.
*/
public class ParseError extends Error {
}
public CParseTreeBuilder(CNode root, IDocument doc) {
fDocument = doc;
fStack.clear();
fStack.push(root);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterClassSpecifier(org.eclipse.cdt.core.parser.ast.IASTClassSpecifier)
*/
public void enterClassSpecifier(IASTClassSpecifier classSpecification) {
String name = classSpecification.getName();
int start = classSpecification.getStartingOffset();
if (classSpecification.getClassKind().equals(ASTClassKind.CLASS)) {
push(ICElement.C_CLASS, name, start);
} else if (classSpecification.getClassKind().equals(ASTClassKind.STRUCT)) {
push(ICElement.C_STRUCT, name, start);
} else if (classSpecification.getClassKind().equals(ASTClassKind.UNION)) {
push(ICElement.C_UNION, name, start);
} else if (classSpecification.getClassKind().equals(ASTClassKind.ENUM)) {
push(ICElement.C_ENUMERATION, name, start);
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterCompilationUnit(org.eclipse.cdt.core.parser.ast.IASTCompilationUnit)
*/
public void enterCompilationUnit(IASTCompilationUnit compilationUnit) {
push(ICElement.C_UNIT, "Translation Unit", 0);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterFunctionBody(org.eclipse.cdt.core.parser.ast.IASTFunction)
*/
public void enterFunctionBody(IASTFunction function) {
push(ICElement.C_FUNCTION, function.getName(), function.getStartingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterInclusion(org.eclipse.cdt.core.parser.ast.IASTInclusion)
*/
public void enterInclusion(IASTInclusion inclusion) {
push(ICElement.C_INCLUDE, inclusion.getName(), inclusion.getStartingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterLinkageSpecification(org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification)
*/
public void enterLinkageSpecification(IASTLinkageSpecification linkageSpec) {
push(ICElement.C_STORAGE_EXTERN, linkageSpec.getLinkageString(), linkageSpec.getStartingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterMethodBody(org.eclipse.cdt.core.parser.ast.IASTMethod)
*/
public void enterMethodBody(IASTMethod method) {
push(ICElement.C_METHOD, method.getName(), method.getStartingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterNamespaceDefinition(org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition)
*/
public void enterNamespaceDefinition(IASTNamespaceDefinition namespaceDefinition) {
push(ICElement.C_NAMESPACE, namespaceDefinition.getName(), namespaceDefinition.getStartingOffset());;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterTemplateDeclaration(org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration)
*/
public void enterTemplateDeclaration(IASTTemplateDeclaration declaration) {
push(ICElement.C_TEMPLATE_VARIABLE, "export", declaration.getStartingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterTemplateInstantiation(org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation)
*/
public void enterTemplateInstantiation(IASTTemplateInstantiation instantiation) {
push(ICElement.C_TEMPLATE_VARIABLE, "template instanciation", instantiation.getStartingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterTemplateSpecialization(org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization)
*/
public void enterTemplateSpecialization(IASTTemplateSpecialization specialization) {
push(ICElement.C_TEMPLATE_VARIABLE, "template specialization", specialization.getStartingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitClassSpecifier(org.eclipse.cdt.core.parser.ast.IASTClassSpecifier)
*/
public void exitClassSpecifier(IASTClassSpecifier classSpecification) {
pop(classSpecification.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitCompilationUnit(org.eclipse.cdt.core.parser.ast.IASTCompilationUnit)
*/
public void exitCompilationUnit(IASTCompilationUnit translationUnit) {
pop(fDocument.getLength());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitFunctionBody(org.eclipse.cdt.core.parser.ast.IASTFunction)
*/
public void exitFunctionBody(IASTFunction function) {
pop(function.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitInclusion(org.eclipse.cdt.core.parser.ast.IASTInclusion)
*/
public void exitInclusion(IASTInclusion inclusion) {
pop(inclusion.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitLinkageSpecification(org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification)
*/
public void exitLinkageSpecification(IASTLinkageSpecification linkageSpec) {
pop(linkageSpec.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitMethodBody(org.eclipse.cdt.core.parser.ast.IASTMethod)
*/
public void exitMethodBody(IASTMethod method) {
pop(method.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitNamespaceDefinition(org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition)
*/
public void exitNamespaceDefinition(IASTNamespaceDefinition namespaceDefinition) {
pop(namespaceDefinition.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitTemplateDeclaration(org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration)
*/
public void exitTemplateDeclaration(IASTTemplateDeclaration declaration) {
pop(declaration.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitTemplateExplicitInstantiation(org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation)
*/
public void exitTemplateExplicitInstantiation(IASTTemplateInstantiation instantiation) {
pop(instantiation.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitTemplateSpecialization(org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization)
*/
public void exitTemplateSpecialization(IASTTemplateSpecialization specialization) {
pop(specialization.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptEnumerationSpecifier(org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier)
*/
public void acceptEnumerationSpecifier(IASTEnumerationSpecifier enumeration) {
push(ICElement.C_ENUMERATION, enumeration.getName(), enumeration.getStartingOffset());
pop(enumeration.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptFunctionDeclaration(org.eclipse.cdt.core.parser.ast.IASTFunction)
*/
public void acceptFunctionDeclaration(IASTFunction function) {
push(ICElement.C_FUNCTION_DECLARATION, function.getName(), function.getStartingOffset());
pop(function.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptMacro(org.eclipse.cdt.core.parser.ast.IASTMacro)
*/
public void acceptMacro(IASTMacro macro) {
push(ICElement.C_MACRO, macro.getName(), macro.getStartingOffset());
pop(macro.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptMethodDeclaration(org.eclipse.cdt.core.parser.ast.IASTMethod)
*/
public void acceptMethodDeclaration(IASTMethod method) {
push(ICElement.C_METHOD_DECLARATION, method.getName(), method.getStartingOffset());
pop(method.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptProblem(org.eclipse.cdt.core.parser.IProblem)
*/
public boolean acceptProblem(IProblem problem) {
int problemId = problem.getID();
if (problem.isError() && ((problemId & IProblem.SYNTAX_RELATED) != 0)) {
throw new ParseError();
}
return true;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptTypedefDeclaration(org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration)
*/
public void acceptTypedefDeclaration(IASTTypedefDeclaration typedef) {
push(ICElement.C_TYPEDEF, typedef.getName(), typedef.getStartingOffset());
pop(typedef.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptUsingDeclaration(org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration)
*/
public void acceptUsingDeclaration(IASTUsingDeclaration usageDeclaration) {
push(ICElement.C_USING, usageDeclaration.usingTypeName(), usageDeclaration.getStartingOffset());
pop(usageDeclaration.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptUsingDirective(org.eclipse.cdt.core.parser.ast.IASTUsingDirective)
*/
public void acceptUsingDirective(IASTUsingDirective usageDirective) {
push(ICElement.C_USING, usageDirective.getNamespaceName(), usageDirective.getStartingOffset());
pop(usageDirective.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptVariable(org.eclipse.cdt.core.parser.ast.IASTVariable)
*/
public void acceptVariable(IASTVariable variable) {
push(ICElement.C_VARIABLE, variable.getName(), variable.getStartingOffset());
pop(variable.getEndingOffset());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptField(org.eclipse.cdt.core.parser.ast.IASTField)
*/
public void acceptField(IASTField field) {
push(ICElement.C_FIELD, field.getName(), field.getStartingOffset());
pop(field.getEndingOffset());
}
private CNode getCurrentContainer() {
return (CNode) fStack.peek();
}
/**
* Adds a new JavaNode with the given type and name to the current container.
*/
private void push(int type, String name, int declarationStart) {
fStack.push(new CNode(getCurrentContainer(), type, name, declarationStart, 0));
}
/**
* Closes the current Java node by setting its end position
* and pops it off the stack.
*/
private void pop(int declarationEnd) {
CNode current = getCurrentContainer();
if (current.getTypeCode() == ICElement.C_UNIT) {
current.setAppendPosition(declarationEnd + 1);
} else {
current.setAppendPosition(declarationEnd);
}
current.setLength(declarationEnd - current.getRange().getOffset() + 1);
fStack.pop();
}
}