Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 67128795336becd3a6d54aacb0c8c647e53d21f1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*******************************************************************************
 * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik  
 * Rapperswil, University of applied sciences and others
 * 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: 
 * Institute for Software - initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;

import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeParameter;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;

/**
 * @author Emanuel Graf
 *
 */
public class NameWriter extends NodeWriter {

	private static final String OPERATOR = "operator "; //$NON-NLS-1$


	/**
	 * @param scribe
	 * @param visitor
	 */
	public NameWriter(Scribe scribe, CPPASTVisitor visitor, NodeCommentMap commentMap) {
		super(scribe, visitor, commentMap);
	}
	
	protected void writeName(IASTName name) {
		if (name instanceof ICPPASTTemplateId) {
			writeTempalteId((ICPPASTTemplateId) name);
		} else if (name instanceof ICPPASTConversionName) {
			scribe.print(OPERATOR);
			((ICPPASTConversionName)name).getTypeId().accept(visitor);
		} else if (name instanceof ICPPASTQualifiedName){
			writeQualifiedName((ICPPASTQualifiedName) name);
		} else {
			scribe.print(name.toString());
		}
		
		if(hasTrailingComments(name)) {
			writeTrailingComments(name);			
		}		
	}
	
	private void writeTempalteId(ICPPASTTemplateId tempId) {
		if(needsTemplateQualifier(tempId)) {
			scribe.print(TEMPLATE);
		}
		scribe.print(tempId.getTemplateName().toString());
		scribe.print('<');
		IASTNode[] nodes = tempId.getTemplateArguments();
		for (int i = 0; i < nodes.length; ++i) {
			nodes[i].accept(visitor);
			if(i + 1 < nodes.length) {
				scribe.print(',');
			}
		}
		scribe.print('>');
		if(isNestedTemplateId(tempId)) {
			scribe.printSpace();
		}
	}
	
	private boolean needsTemplateQualifier(ICPPASTTemplateId templId){
		if (templId.getParent() instanceof ICPPASTQualifiedName) {
			ICPPASTQualifiedName qName = (ICPPASTQualifiedName)  templId.getParent();
			return isDependentName(qName, templId);			
		}
		return false;
	}
	
	private boolean isDependentName(ICPPASTQualifiedName qname, ICPPASTTemplateId tempId) {
		IASTName[] names = qname.getNames();
		int i = 0;
		for(;i < names.length; ++i){
			if(names[i] == tempId){
				return isDependentName(qname, tempId, i);
			}
		}
		return false;
	}

	private boolean isDependentName(ICPPASTQualifiedName qname,
			ICPPASTTemplateId tempId, int i) {
		if(i <= 0){
			return false;
		}else{
			if (qname.getNames()[i-1] instanceof ICPPASTTemplateId) {
				return true;
			}else{
				IBinding binding = qname.getNames()[i-1].resolveBinding();
				if (binding instanceof CPPTemplateTypeParameter) {
					return true;
				}
			}
		}
		return isDependentName(qname, tempId, i-1);
	}

	private boolean isNestedTemplateId(IASTNode node) {
		while((node = node.getParent()) != null) {
			if (node instanceof ICPPASTTemplateId) {
				return true;
			}
		}
		return false;
	}


	private void writeQualifiedName(ICPPASTQualifiedName qname) {
		IASTName[] nodes = qname.getNames();
		for (int i = 0; i < nodes.length; ++i) {
			nodes[i].accept(visitor);
			if(i + 1 < nodes.length) {
				scribe.print(COLON_COLON);
			}
		}
	}
}

Back to the top