typebuilder.java

来自「plugin for eclipse」· Java 代码 · 共 352 行

JAVA
352
字号
/*
 * Created on Jun 7, 2005
 * 
 * TODO To change the template for this generated file go to Window -
 * Preferences - Java - Code Style - Code Templates
 */
package isis.anp.nesc.ot.types;

import isis.anp.common.CodeLocation;
import isis.anp.common.ObjectTreeBuilderContext;
import isis.anp.common.ParserMessage;
import isis.anp.nesc.ot.AbstractDeclarator;
import isis.anp.nesc.ot.ArrayConstructor;
import isis.anp.nesc.ot.CompoundTypeSpecifier;
import isis.anp.nesc.ot.Declaration;
import isis.anp.nesc.ot.EnumSpecifier;
import isis.anp.nesc.ot.NameConflictException;
import isis.anp.nesc.ot.ParameterTypeList;
import isis.anp.nesc.ot.PointerGroup;
import isis.anp.nesc.ot.StructSpecifier;
import isis.anp.nesc.ot.TypeQualifier;
import isis.anp.nesc.ot.TypeQualifiers;
import isis.anp.nesc.ot.TypeResolutionException;
import isis.anp.nesc.ot.TypeSpecifier;
import isis.anp.nesc.ot.TypedefName;
import isis.anp.nesc.ot.TypeofName;
import isis.anp.nesc.ot.UnionSpecifier;
import isis.anp.nesc.ot.scope.Scope;
import isis.anp.nesc.ot.scope.Symbol;

import java.util.List;


public class TypeBuilder {
	protected TypeQualifiers typeQualifiers = new TypeQualifiers();

	protected Type typeProduct;

	protected AbstractDeclarator nameProduct;

	/**
	 * @return Returns the type.
	 */
	public Type getType() {
		//		System.out.println("BuilderObj.getType: "+type);
		return typeProduct;
	}

	/**
	 * Add a type qualifier to the type being bilt.
	 * 
	 * @param tq
	 *            Type qualifier
	 */
	public void addTypeQualifier(TypeQualifier tq) {
		typeQualifiers.add(tq);
	}

	private CompoundType createCompoundType(CompoundTypeSpecifier cts, ObjectTreeBuilderContext ctx) {
		if (cts instanceof StructSpecifier) {
			return new StructType((StructSpecifier) cts);
		} else if (cts instanceof UnionSpecifier) {
			return new UnionType((UnionSpecifier) cts);
		} else if (cts instanceof EnumSpecifier) {
			((EnumSpecifier) cts).addEnumeratorConstantsToScope(ctx);
			return new EnumType((EnumSpecifier) cts);
			
		}
		
		// we never get here...
		return null;
	}

	/**
	 * Add a type specifier to the type being built.
	 * 
	 * @param ts
	 *            Type specifier.
	 * @throws TypeResolutionException
	 */
	public void addTypeSpecifier(TypeSpecifier ts) {
		ObjectTreeBuilderContext ctx = ts.getContext();
		Scope currentScope = ctx.getCurrentScope();
		String specifierName = ts.getSpecifierName();

		if (typeProduct == null) {
			// no type has been built so far

			if (ts instanceof CompoundTypeSpecifier) {
				specifierName = ts.getDefNode().getText() + " " + specifierName;
				// it's specifier of a compound type
				//System.out.println("TypeBuilder:" + specifierName + "it's specifier of a compound type");
				CompoundTypeSpecifier cts = (CompoundTypeSpecifier) ts;
				CompoundType prevType = (CompoundType) currentScope.findSymbol(specifierName);

				if (prevType == null) {
					// name not found
					//System.out.println("TypeBuilder:" + specifierName + ":name not found");
					typeProduct = createCompoundType(cts, ctx);
					currentScope.addSymbol((CompoundType)typeProduct);
					
					// continue working on a clone
					typeProduct = (Type)typeProduct.clone();
					
				} else {
					// name found
					//System.out.println("TypeBuilder:" + specifierName + ":name found");
					if (prevType.getParentScope().equals(currentScope)) {
						// name found in current scope
						//System.out.println("TypeBuilder:" + specifierName + ":name found in current scope");
						if (prevType.isComplete()) {
							// complete type found in current scope
							//System.out.println("TypeBuilder:" + specifierName + ":complete type found in current scope");
							if (cts.isComplete()) {
								// both types would be complete
								//System.out.println("TypeBuilder:" + specifierName + ":both types would be complete");							

								NameConflictException nce = new NameConflictException(
										prevType.getNameNode(), cts
												.getSpecifierNameNode());
								ctx.addMsg(new ParserMessage(ParserMessage.ERROR, nce.getMessage(),
										new CodeLocation(cts
												.getSpecifierNameNode()), nce));
							} else {
								// only previous type is complete
								//System.out.println("TypeBuilder:" + specifierName + ":only previous type is complete");							

								typeProduct = createCompoundType(cts, ctx);
								((CompoundType) prevType).complete((CompoundType) typeProduct);
							}
						} else {
							// incomplete type found in current scope
							//System.out.println("TypeBuilder:" + specifierName + ":incomplete type found in current scope");
							if (cts.isComplete()) {
								// new type completes previous one
								//System.out.println("TypeBuilder:" + specifierName + ":new type completes previous one");
								typeProduct = createCompoundType(cts, ctx);
								
								((CompoundType) typeProduct).complete((CompoundType) prevType);
							

							} else {
								// both new and previous types are incomplete
								//System.out.println("TypeBuilder:" + specifierName + ":both new and previous types are incomplete");
								typeProduct = prevType;

								// continue working on a clone
								typeProduct = (Type)typeProduct.clone();								
							}
						}
					} else {
						// name found in an upper scope
						//System.out.println("TypeBuilder:" + specifierName + ":name found in an upper scope");
						
						if (cts.isComplete()) {
							// new type is complete, it shadows the previous one
							//System.out.println("TypeBuilder:" + specifierName + ":new type is complete, it shadows the previous one");							
							typeProduct = createCompoundType(cts, ctx);
							currentScope.addSymbol((CompoundType)typeProduct);

							// continue working on a clone
							typeProduct = (Type)typeProduct.clone();
							
						} else {
							// new type is incomplete
							//System.out.println("TypeBuilder:" + specifierName + ":new type is incomplete");														
							if (prevType.isComplete()) {
								// previous type is complete
								//System.out.println("TypeBuilder:" + specifierName + ":previous type is complete");								
								typeProduct = createCompoundType(cts, ctx);
								prevType.complete((CompoundType)typeProduct);
							} else {
								// previous type is incomplete
								//System.out.println("TypeBuilder:" + specifierName + ":previous type is incomplete");
								typeProduct = createCompoundType(cts, ctx);
							}
						}
					}
				}
			} // end if (ts is a CompoundTypeSpecifier)

			else if (ts instanceof TypedefName) {
			    
				Symbol symbol = currentScope.findSymbol(specifierName);
				
				if (symbol instanceof TypeReference) {
					typeProduct = (TypeReference) symbol;

					// continue working on a clone
					typeProduct = (Type)typeProduct.clone();
					
				} else {
					TypeResolutionException tre = new TypeResolutionException(
							"Type not found: " + specifierName, ts
									.getSpecifierNameNode());
					ctx.addMsg(new ParserMessage(ParserMessage.ERROR, tre.getMessage(),
							new CodeLocation(ts.getSpecifierNameNode()), tre));
				}
			} // end if (ts is a TypedefName)

			else if (ts instanceof TypeofName) {
				Symbol symbol = currentScope.findSymbol(specifierName);
				
				if (symbol instanceof Declaration) {
					typeProduct = ((Declaration) symbol).getType();

					// continue working on a clone
					typeProduct = (Type)typeProduct.clone();
					
				} else {
					TypeResolutionException tre = new TypeResolutionException(
							"Declaration not found: " + specifierName, ts
									.getSpecifierNameNode());
					ctx.addMsg(new ParserMessage(ParserMessage.ERROR, tre.getMessage(),
							new CodeLocation(ts.getSpecifierNameNode()), tre));
				}
			} // end if (ts is a TypeofName)

			else {
				// ts is a simple type specifier
				typeProduct = new SimpleType();
				((SimpleType) typeProduct).addTypeSpecifier(ts);
			}

			// add temporarily stored type qualifier to the type
			if(typeProduct!=null) {
				typeProduct.addTypeQualifiers(typeQualifiers);
			}

		} // end if (typeProduct is null)

		else if (typeProduct instanceof SimpleType) {
			((SimpleType) typeProduct).addTypeSpecifier(ts);
		}
		
		else {
			TypeResolutionException tre = new TypeResolutionException(
					"Error building type: invalid type specifier: "
							+ specifierName, ts.getSpecifierNameNode());
			ctx.addMsg(new ParserMessage(ParserMessage.ERROR, tre.getMessage(), new CodeLocation(ts
					.getSpecifierNameNode()), tre));
		}
	}

	/**
	 * Add a declarator to a type. The builder extracts the additional type
	 * information from the declarator (pointer constructors, array constructors
	 * and function constructors).
	 * 
	 * @param aDeclr
	 *            The declarator.
	 * @return @throws
	 *         TypeResolutionException
	 */
	public AbstractDeclarator addDeclarator(AbstractDeclarator aDeclr)
			throws TypeResolutionException {
		// resolve pointer group (this will remove everything from the
		// pointergroup)
		resolvePointerGroup(aDeclr.getPointerGroup());

		// resolve array constructors and parameter type lists (this will remove
		// all array constructors and parameter type lists from the declarator)
		resolveArrayAndFunctionConstructors(aDeclr.getPAList());

		// resolve parenthesized declarator
		if (aDeclr.getNestedDecl() != null) {
			return addDeclarator(aDeclr.getNestedDecl());
		}

		// set declarator to leaf declarator
		this.nameProduct = aDeclr;
		// return the leaf declarator
		return this.nameProduct;
	}

	/**
	 * @param acs
	 */
	private void resolveArrayAndFunctionConstructors(List cList) {
		if (cList.isEmpty())
			return;
		Object c = cList.remove(cList.size() - 1);

		if (c instanceof ArrayConstructor) {
			typeProduct = new ArrayType(typeProduct, ((ArrayConstructor) c)
					.getSizeExpression());
		} else if (c instanceof ParameterTypeList) {
			typeProduct = new FunctionType(typeProduct, (ParameterTypeList) c);
		}

		// continue recursively
		resolveArrayAndFunctionConstructors(cList);
	}

	/**
	 * @param group
	 * @throws TypeResolutionException
	 */
	private void resolvePointerGroup(PointerGroup pg)
			throws TypeResolutionException {
		if (pg == null)
			return;
		Object member = pg.removeFirstMember();
		if (member == null)
			return;
		if (member instanceof String) {
			// it's a star
			if (((String) member).equals("*")) {
				// construct a new pointer type enclosing the actual type
				typeProduct = new PointerType(typeProduct);
			} else {
				throw new TypeResolutionException(
						"Invalid member in pointer group ('*' expected)",
						nameProduct.getDefNode());
			}
		} else if (member instanceof TypeQualifier) {
			// it's const or volatile
			if (typeProduct instanceof PointerType) {
				typeProduct.addTypeQualifier((TypeQualifier) member);
			} else {
				throw new TypeResolutionException(
						"Cannot apply type qualifier to non-pointer type",
						nameProduct.getDefNode());
			}
		} else {
			throw new TypeResolutionException(
					"Invalid member in pointer group " + member.toString()
							+ " ('*' or const or volatile expected)",
					nameProduct.getDefNode());
		}

		// continue recursively
		resolvePointerGroup(pg);
	}

	public Object clone() {
		TypeBuilder rval = new TypeBuilder();
		rval.typeQualifiers = (TypeQualifiers) this.typeQualifiers.clone();
		// FIXME: do a deep copy
//		rval.typeProduct = this.typeProduct.clone();
		rval.typeProduct = this.typeProduct;		
		return rval;
	}

	/**
	 * @return Returns the declarator.
	 */
	public AbstractDeclarator getDeclarator() {
		return nameProduct;
	}

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?