use of mrmathami.cia.cpp.ast.FunctionNode in project Cpp4CIA by thanhminhmr.
the class AstBuilder method cleanUp.
private void cleanUp() {
bindingNodeMap.clear();
// remove all children of variable and function node
for (final CppNode node : rootNode) {
if (node instanceof FunctionNode || node instanceof VariableNode) {
node.collapse();
}
}
// clean up nodes
for (final CppNode node : integralNodeMap.values()) {
node.removeChildren();
node.removeAllDependency();
}
// replace unknown node with integral node
for (final IntegralNode unknownNode : unknownNodes) {
if (unknownNode.getRoot() != rootNode)
continue;
final CppNode parent = unknownNode.getParent();
assert parent != null;
if (unknownNode.getAllDependencyFrom().isEmpty() && unknownNode.getAllDependencyTo().isEmpty()) {
unknownNode.collapseToParent();
} else {
unknownNode.collapse();
final CppNode integralNode = integralNodeMap.get(unknownNode.getName());
if (integralNode != null) {
unknownNode.transfer(integralNode);
integralNode.transferAllDependency(parent);
} else {
unknownNode.move(rootNode);
unknownNode.transferAllDependency(parent);
integralNodeMap.put(unknownNode.getName(), unknownNode);
}
}
}
unknownNodes.clear();
// merge duplicates
{
final CppNode.Matcher matcher = new CppNode.Matcher();
mergeDuplicate(matcher, rootNode);
for (final CppNode node : rootNode) {
mergeDuplicate(matcher, node);
}
}
}
use of mrmathami.cia.cpp.ast.FunctionNode in project Cpp4CIA by thanhminhmr.
the class AstBuilder method createOverride.
private void createOverride() {
final CppNode.Matcher matcher = new CppNode.Matcher();
for (final CppNode node : rootNode) {
if (!(node instanceof ClassNode))
continue;
final ClassNode classNode = (ClassNode) node;
final Set<CppNode> classBases = classNode.getBases();
final List<FunctionNode> classFunctions = classNode.getFunctions();
if (classBases.isEmpty() || classFunctions.isEmpty())
continue;
final Map<CppNode.Wrapper, FunctionNode> classFunctionsMatched = new HashMap<>();
for (final FunctionNode classFunction : classFunctions) {
final CppNode.Wrapper wrapper = new CppNode.Wrapper(classFunction, CppNode.MatchLevel.PROTOTYPE_IDENTICAL, matcher);
classFunctionsMatched.put(wrapper, classFunction);
}
for (final CppNode classBase : classBases) {
if (!(classBase instanceof ClassNode))
continue;
for (final FunctionNode baseFunction : ((ClassNode) classBase).getFunctions()) {
final CppNode.Wrapper wrapper = new CppNode.Wrapper(baseFunction, CppNode.MatchLevel.PROTOTYPE_IDENTICAL, matcher);
final FunctionNode functionNode = classFunctionsMatched.get(wrapper);
if (functionNode != null) {
functionNode.addDependencyTo(baseFunction, DependencyType.OVERRIDE);
}
}
}
}
}
use of mrmathami.cia.cpp.ast.FunctionNode in project Cpp4CIA by thanhminhmr.
the class AstBuilder method createFromDeclarator.
@Nonnull
private CppNode createFromDeclarator(@Nonnull CppNode parentNode, @Nullable CppNode typeNode, @Nonnull IASTDeclarator declarator, boolean isTypedef) {
final IASTName declaratorName = declarator.getName();
final IBinding declaratorBinding = declaratorName.resolveBinding();
final String signature = ASTStringUtil.getSignatureString(declarator);
if (declarator instanceof IASTAmbiguousDeclarator) {
return createUnknownNode(parentNode, declaratorBinding, declaratorName.toString(), isTypedef);
} else if (declarator instanceof ICPPASTFunctionDeclarator) {
// region Function
final ICPPASTFunctionDeclarator functionDeclarator = (ICPPASTFunctionDeclarator) declarator;
final CppNode functionNode = createNode(declaratorBinding, declaratorName, signature, new FunctionNode(), parentNode);
if (functionNode instanceof FunctionNode) {
if (!(typeNode instanceof IntegralNode) || !typeNode.getName().isEmpty()) {
((FunctionNode) functionNode).setType(typeNode);
// functionNode.addDependencyTo(typeNode, DependencyType.USE);
}
for (final ICPPASTParameterDeclaration functionParameter : functionDeclarator.getParameters()) {
final CppNode parameterType = createFromDeclSpecifier(functionNode, functionParameter.getDeclSpecifier());
if (!(parameterType instanceof IntegralNode) || !parameterType.getName().equals("void")) {
createFromDeclarator(functionNode, parameterType, functionParameter.getDeclarator(), true);
((FunctionNode) functionNode).addParameter(parameterType);
// functionNode.addDependencyTo(parameterType, DependencyType.USE);
}
}
final IASTInitializer initializer = declarator.getInitializer();
if (initializer != null && initializer.getChildren().length > 0) {
((FunctionNode) functionNode).setBody(initializer.getRawSignature());
childrenCreationQueue.add(Pair.mutableOf(functionNode, initializer));
}
}
// endregion
return functionNode;
} else if (declarator instanceof ICPPASTDeclarator) {
if (isTypedef) {
// region Typedef
final CppNode typedefNode = createNode(declaratorBinding, declaratorName, signature, new TypedefNode(), parentNode);
if (typedefNode instanceof TypedefNode) {
((TypedefNode) typedefNode).setType(typeNode);
// typedefNode.addDependencyTo(typeNode, DependencyType.USE);
}
// endregion
return typedefNode;
} else {
// region Variable
final CppNode variableNode = createNode(declaratorBinding, declaratorName, signature, new VariableNode(), parentNode);
if (variableNode instanceof VariableNode) {
((VariableNode) variableNode).setType(typeNode);
// variableNode.addDependencyTo(typeNode, DependencyType.USE);
final IASTInitializer initializer = declarator.getInitializer();
if (initializer != null) {
((VariableNode) variableNode).setBody(initializer.getRawSignature());
childrenCreationQueue.add(Pair.mutableOf(variableNode, initializer));
}
}
// endregion
return variableNode;
}
} else {
// todo: debug?
throw new IllegalArgumentException("createFromDeclarator(declarator = (" + Utilities.objectIdentifyString(declarator) + "))");
}
}
use of mrmathami.cia.cpp.ast.FunctionNode in project Cpp4CIA by thanhminhmr.
the class AstBuilder method createChildrenFromDeclaration.
@Nonnull
private List<CppNode> createChildrenFromDeclaration(@Nonnull CppNode parentNode, @Nonnull IASTDeclaration declaration) {
if (declaration instanceof ICPPASTVisibilityLabel || declaration instanceof IASTASMDeclaration || declaration instanceof IASTProblemDeclaration || declaration instanceof ICPPASTStaticAssertDeclaration || declaration instanceof ICPPASTExplicitTemplateInstantiation || declaration instanceof ICPPASTInitCapture) {
// skipped
return List.of();
} else if (declaration instanceof ICPPASTUsingDeclaration) {
// region Using Declaration / Directive
final IASTName declarationName = ((ICPPASTUsingDeclaration) declaration).getName();
final IBinding declarationBinding = declarationName.resolveBinding();
final CppNode declarationNode = createNode(declarationBinding, declarationName, null, new TypedefNode(), parentNode);
if (declarationNode instanceof TypedefNode && declarationBinding instanceof ICPPUsingDeclaration) {
for (final IBinding delegateBinding : ((ICPPUsingDeclaration) declarationBinding).getDelegates()) {
createUnknownNode(declarationNode, delegateBinding, declarationName.toString(), true);
}
}
// endregion
return List.of(declarationNode);
} else if (declaration instanceof ICPPASTUsingDirective) {
// region Using Declaration / Directive
final IASTName usingName = ((ICPPASTUsingDirective) declaration).getQualifiedName();
final CppNode usingNode = createUnknownNode(parentNode, usingName.resolveBinding(), usingName.toString(), true);
// endregion
return List.of(usingNode);
} else if (declaration instanceof ICPPASTLinkageSpecification) {
final ICPPASTLinkageSpecification linkageSpecification = (ICPPASTLinkageSpecification) declaration;
// region extern "C"
final List<CppNode> childrenNode = new ArrayList<>();
for (final IASTDeclaration linkageDeclaration : linkageSpecification.getDeclarations(false)) {
childrenNode.addAll(createChildrenFromDeclaration(parentNode, linkageDeclaration));
}
// endregion
return childrenNode;
} else if (declaration instanceof ICPPASTNamespaceDefinition) {
final ICPPASTNamespaceDefinition namespaceDefinition = (ICPPASTNamespaceDefinition) declaration;
// region Namespace
final IASTName namespaceName = namespaceDefinition.getName();
final CppNode namespaceNode = createNode(namespaceName.resolveBinding(), namespaceName, null, new NamespaceNode(), parentNode);
for (final IASTDeclaration namespaceDeclaration : namespaceDefinition.getDeclarations(false)) {
createChildrenFromDeclaration(namespaceNode, namespaceDeclaration);
}
// endregion
return List.of(namespaceNode);
} else if (declaration instanceof IASTSimpleDeclaration) {
final IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
// region Simple Declaration
final IASTDeclSpecifier simpleSpecifier = simpleDeclaration.getDeclSpecifier();
final CppNode simpleNodeType = createFromDeclSpecifier(parentNode, simpleSpecifier);
final List<CppNode> simpleNodeList = new ArrayList<>();
final boolean isTypedef = simpleSpecifier.getStorageClass() == IASTDeclSpecifier.sc_typedef;
for (final IASTDeclarator simpleDeclarator : simpleDeclaration.getDeclarators()) {
simpleNodeList.add(createFromDeclarator(parentNode, simpleNodeType, simpleDeclarator, isTypedef));
}
// endregion
return !simpleNodeList.isEmpty() ? simpleNodeList : List.of(simpleNodeType);
} else if (declaration instanceof ICPPASTFunctionDefinition) {
final ICPPASTFunctionDefinition functionDefinition = (ICPPASTFunctionDefinition) declaration;
// region Function
final CppNode functionReturnType = createFromDeclSpecifier(parentNode, functionDefinition.getDeclSpecifier());
final CppNode functionNode = createFromDeclarator(parentNode, functionReturnType, functionDefinition.getDeclarator(), false);
final StringBuilder functionBodyBuilder = new StringBuilder(functionNode instanceof FunctionNode ? Objects.requireNonNullElse(((FunctionNode) functionNode).getBody(), "") : "");
// function with constructor
for (final ICPPASTConstructorChainInitializer memberChainInitializer : functionDefinition.getMemberInitializers()) {
final IASTName memberName = memberChainInitializer.getMemberInitializerId();
createUnknownNode(functionNode, memberName.resolveBinding(), memberName.toString(), true);
functionBodyBuilder.append(memberName).append('(');
final IASTInitializer memberInitializer = memberChainInitializer.getInitializer();
if (memberInitializer != null) {
childrenCreationQueue.add(Pair.mutableOf(functionNode, memberInitializer));
functionBodyBuilder.append(memberInitializer.getRawSignature());
}
functionBodyBuilder.append(");");
}
// function with body
final IASTStatement functionBody = functionDefinition.getBody();
if (functionBody != null && functionBody.getChildren().length > 0) {
childrenCreationQueue.add(Pair.mutableOf(functionNode, functionBody));
functionBodyBuilder.append(functionBody.getRawSignature());
}
if (functionBodyBuilder.length() > 0 && functionNode instanceof FunctionNode) {
((FunctionNode) functionNode).setBody(functionBodyBuilder.toString());
}
// endregion
return List.of(functionNode);
} else if (declaration instanceof ICPPASTTemplateDeclaration) {
final ICPPASTTemplateDeclaration templateDeclaration = (ICPPASTTemplateDeclaration) declaration;
// region Template
final List<CppNode> innerNodeList = createChildrenFromDeclaration(parentNode, templateDeclaration.getDeclaration());
if (!innerNodeList.isEmpty()) {
final CppNode innerNode = innerNodeList.get(0);
for (final ICPPASTTemplateParameter templateParameter : templateDeclaration.getTemplateParameters()) {
createFromTemplateParameter(innerNode, templateParameter);
}
}
// endregion
return innerNodeList;
} else if (declaration instanceof ICPPASTNamespaceAlias) {
final ICPPASTNamespaceAlias namespaceAlias = (ICPPASTNamespaceAlias) declaration;
// region Namespace Alias
final IASTName aliasName = namespaceAlias.getAlias();
final CppNode aliasNode = createNode(aliasName.resolveBinding(), aliasName, null, new TypedefNode(), parentNode);
final IASTName mappingName = namespaceAlias.getMappingName();
createUnknownNode(aliasNode, mappingName.resolveBinding(), mappingName.toString(), true);
// endregion
return List.of(aliasNode);
} else if (declaration instanceof ICPPASTAliasDeclaration) {
final ICPPASTAliasDeclaration aliasDefinition = (ICPPASTAliasDeclaration) declaration;
// region Alias
final IASTName aliasName = aliasDefinition.getAlias();
final ICPPASTTypeId aliasTypeId = aliasDefinition.getMappingTypeId();
final IASTDeclSpecifier aliasDeclSpecifier = aliasTypeId.getDeclSpecifier();
final IASTDeclarator aliasDeclarator = aliasTypeId.getAbstractDeclarator();
final CppNode aliasNode = createNode(aliasName.resolveBinding(), aliasName, ASTStringUtil.getSignatureString(aliasDeclSpecifier, aliasDeclarator), new TypedefNode(), parentNode);
final CppNode aliasType = createFromDeclSpecifier(aliasNode, aliasDeclSpecifier);
createFromDeclarator(aliasNode, aliasType, aliasDeclarator, false);
// endregion
return List.of(aliasNode);
} else {
// todo: debug?
throw new IllegalArgumentException("createChildrenFromDeclaration(parentNode = (" + Utilities.objectIdentifyString(parentNode) + "), declaration = (" + Utilities.objectIdentifyString(declaration) + "))");
}
}
Aggregations