001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.corext.dom;
011:
012: import java.util.ArrayList;
013: import java.util.List;
014:
015: import org.eclipse.jdt.core.dom.AST;
016: import org.eclipse.jdt.core.dom.ASTNode;
017: import org.eclipse.jdt.core.dom.ASTParser;
018: import org.eclipse.jdt.core.dom.CompilationUnit;
019: import org.eclipse.jdt.core.dom.Expression;
020: import org.eclipse.jdt.core.dom.ITypeBinding;
021: import org.eclipse.jdt.core.dom.InfixExpression;
022: import org.eclipse.jdt.core.dom.MethodDeclaration;
023: import org.eclipse.jdt.core.dom.Modifier;
024: import org.eclipse.jdt.core.dom.Name;
025: import org.eclipse.jdt.core.dom.PrimitiveType;
026: import org.eclipse.jdt.core.dom.Type;
027: import org.eclipse.jdt.core.dom.TypeDeclaration;
028: import org.eclipse.jdt.core.dom.TypeParameter;
029: import org.eclipse.jdt.core.dom.VariableDeclaration;
030: import org.eclipse.jdt.core.dom.InfixExpression.Operator;
031:
032: public class ASTNodeFactory {
033:
034: private static final String STATEMENT_HEADER = "class __X__ { void __x__() { "; //$NON-NLS-1$
035: private static final String STATEMENT_FOOTER = "}}"; //$NON-NLS-1$
036:
037: private static final String TYPE_HEADER = "class __X__ { abstract "; //$NON-NLS-1$
038: private static final String TYPE_FOOTER = " __f__(); }}"; //$NON-NLS-1$
039:
040: private static final String TYPEPARAM_HEADER = "class __X__ { abstract <"; //$NON-NLS-1$
041: private static final String TYPEPARAM_FOOTER = "> void __f__(); }}"; //$NON-NLS-1$
042:
043: private static class PositionClearer extends GenericVisitor {
044:
045: public PositionClearer() {
046: super (true);
047: }
048:
049: protected boolean visitNode(ASTNode node) {
050: node.setSourceRange(-1, 0);
051: return true;
052: }
053: }
054:
055: private ASTNodeFactory() {
056: // no instance;
057: }
058:
059: public static ASTNode newStatement(AST ast, String content) {
060: StringBuffer buffer = new StringBuffer(STATEMENT_HEADER);
061: buffer.append(content);
062: buffer.append(STATEMENT_FOOTER);
063: ASTParser p = ASTParser.newParser(ast.apiLevel());
064: p.setSource(buffer.toString().toCharArray());
065: CompilationUnit root = (CompilationUnit) p.createAST(null);
066: ASTNode result = ASTNode.copySubtree(ast, NodeFinder.perform(
067: root, STATEMENT_HEADER.length(), content.length()));
068: result.accept(new PositionClearer());
069: return result;
070: }
071:
072: public static Name newName(AST ast, String qualifiedName) {
073: return ast.newName(qualifiedName);
074: }
075:
076: public static TypeParameter newTypeParameter(AST ast, String content) {
077: StringBuffer buffer = new StringBuffer(TYPEPARAM_HEADER);
078: buffer.append(content);
079: buffer.append(TYPEPARAM_FOOTER);
080: ASTParser p = ASTParser.newParser(ast.apiLevel());
081: p.setSource(buffer.toString().toCharArray());
082: CompilationUnit root = (CompilationUnit) p.createAST(null);
083: List list = root.types();
084: TypeDeclaration typeDecl = (TypeDeclaration) list.get(0);
085: MethodDeclaration methodDecl = typeDecl.getMethods()[0];
086: TypeParameter tp = (TypeParameter) methodDecl.typeParameters()
087: .get(0);
088: ASTNode result = ASTNode.copySubtree(ast, tp);
089: result.accept(new PositionClearer());
090: return (TypeParameter) result;
091: }
092:
093: public static Type newType(AST ast, String content) {
094: StringBuffer buffer = new StringBuffer(TYPE_HEADER);
095: buffer.append(content);
096: buffer.append(TYPE_FOOTER);
097: ASTParser p = ASTParser.newParser(ast.apiLevel());
098: p.setSource(buffer.toString().toCharArray());
099: CompilationUnit root = (CompilationUnit) p.createAST(null);
100: List list = root.types();
101: TypeDeclaration typeDecl = (TypeDeclaration) list.get(0);
102: MethodDeclaration methodDecl = typeDecl.getMethods()[0];
103: ASTNode type = methodDecl.getReturnType2();
104: ASTNode result = ASTNode.copySubtree(ast, type);
105: result.accept(new PositionClearer());
106: return (Type) result;
107: }
108:
109: /**
110: * Returns the new type node corresponding to the type of the given declaration
111: * including the extra dimensions.
112: * @param ast The AST to create the resulting type with.
113: * @param declaration The variable declaration to get the type from
114: * @return A new type node created with the given AST.
115: */
116: public static Type newType(AST ast, VariableDeclaration declaration) {
117: Type type = ASTNodes.getType(declaration);
118: int extraDim = declaration.getExtraDimensions();
119:
120: type = (Type) ASTNode.copySubtree(ast, type);
121: for (int i = 0; i < extraDim; i++) {
122: type = ast.newArrayType(type);
123: }
124: return type;
125: }
126:
127: /**
128: * Returns an expression that is assignable to the given type. <code>null</code> is
129: * returned if the type is the 'void' type.
130: *
131: * @param ast The AST to create the expression for
132: * @param type The type of the returned expression
133: * @param extraDimensions Extra dimensions to the type
134: * @return Returns the Null-literal for reference types, a boolen-literal for a boolean type, a number
135: * literal for primitive types or <code>null</code> if the type is void.
136: */
137: public static Expression newDefaultExpression(AST ast, Type type,
138: int extraDimensions) {
139: if (extraDimensions == 0 && type.isPrimitiveType()) {
140: PrimitiveType primitiveType = (PrimitiveType) type;
141: if (primitiveType.getPrimitiveTypeCode() == PrimitiveType.BOOLEAN) {
142: return ast.newBooleanLiteral(false);
143: } else if (primitiveType.getPrimitiveTypeCode() == PrimitiveType.VOID) {
144: return null;
145: } else {
146: return ast.newNumberLiteral("0"); //$NON-NLS-1$
147: }
148: }
149: return ast.newNullLiteral();
150: }
151:
152: /**
153: * Returns an expression that is assignable to the given typebinding. <code>null</code> is
154: * returned if the type is the 'void' type.
155: *
156: * @param ast The AST to create the expression for
157: * @param type The type binding to which the returned expression is compatible to
158: * @return Returns the Null-literal for reference types, a boolen-literal for a boolean type, a number
159: * literal for primitive types or <code>null</code> if the type is void.
160: */
161: public static Expression newDefaultExpression(AST ast,
162: ITypeBinding type) {
163: if (type.isPrimitive()) {
164: String name = type.getName();
165: if ("boolean".equals(name)) { //$NON-NLS-1$
166: return ast.newBooleanLiteral(false);
167: } else if ("void".equals(name)) { //$NON-NLS-1$
168: return null;
169: } else {
170: return ast.newNumberLiteral("0"); //$NON-NLS-1$
171: }
172: }
173: return ast.newNullLiteral();
174: }
175:
176: /**
177: * Returns a list of newly created Modifier nodes corresponding to the given modfier flags.
178: * @param ast The ast to create the nodes for.
179: * @param modifiers The modifier flags describing the modifier nodes to create.
180: * @return Returns a list of nodes of type {@link Modifier}.
181: */
182: public static List newModifiers(AST ast, int modifiers) {
183: return ast.newModifiers(modifiers);
184: }
185:
186: /**
187: * Returns a list of newly created Modifier nodes corresponding to a given list of existing modifiers.
188: * @param ast The ast to create the nodes for.
189: * @param modifierNodes The modifier nodes describing the modifier nodes to create. Only
190: * nodes of type {@link Modifier} are looked at and cloned. To create a full copy of the list consider
191: * to use {@link ASTNode#copySubtrees(AST, List)}.
192: * @return Returns a list of nodes of type {@link Modifier}.
193: */
194: public static List newModifiers(AST ast, List modifierNodes) {
195: List res = new ArrayList(modifierNodes.size());
196: for (int i = 0; i < modifierNodes.size(); i++) {
197: Object curr = modifierNodes.get(i);
198: if (curr instanceof Modifier) {
199: res
200: .add(ast.newModifier(((Modifier) curr)
201: .getKeyword()));
202: }
203: }
204: return res;
205: }
206:
207: public static Expression newInfixExpression(AST ast,
208: Operator operator, ArrayList/*<Expression>*/operands) {
209: if (operands.size() == 1)
210: return (Expression) operands.get(0);
211:
212: InfixExpression result = ast.newInfixExpression();
213: result.setOperator(operator);
214: result.setLeftOperand((Expression) operands.get(0));
215: result.setRightOperand((Expression) operands.get(1));
216: result.extendedOperands().addAll(
217: operands.subList(2, operands.size()));
218: return result;
219: }
220:
221: }
|