All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aspectj.ajdt.internal.compiler.ast.DeclareDeclaration Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/* *******************************************************************
 * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
 * All rights reserved.
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Public License v 2.0
 * which accompanies this distribution and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
 *
 * Contributors:
 *     PARC     initial implementation
 * ******************************************************************/

package org.aspectj.ajdt.internal.compiler.ast;

//import java.util.List;

import java.util.Collection;
import java.util.Iterator;

import org.aspectj.ajdt.internal.compiler.lookup.EclipseScope;
import org.aspectj.org.eclipse.jdt.core.Flags;
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
import org.aspectj.weaver.AjAttribute;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.patterns.Declare;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
import org.aspectj.weaver.patterns.DeclareParents;
import org.aspectj.weaver.patterns.DeclarePrecedence;
import org.aspectj.weaver.patterns.DeclareSoft;
import org.aspectj.weaver.patterns.FormalBinding;

public class DeclareDeclaration extends AjMethodDeclaration {

	public Declare declareDecl;

	/**
	 * Constructor for IntraTypeDeclaration.
	 */
	public DeclareDeclaration(CompilationResult result, Declare symbolicDeclare) {
		super(result);

		this.declareDecl = symbolicDeclare;
		if (declareDecl != null) {
			// AMC added init of declarationSourceXXX fields which are used
			// in AsmBuilder for processing of MethodDeclaration locations.
			declarationSourceStart = sourceStart = declareDecl.getStart();
			declarationSourceEnd = sourceEnd = declareDecl.getEnd();
		}
		// ??? we might need to set parameters to be empty
		this.returnType = TypeReference.baseTypeReference(T_void, 0, null);
	}

	public void addAtAspectJAnnotations() {
		Annotation annotation = null;
		if (declareDecl instanceof DeclareAnnotation) {
			DeclareAnnotation da = (DeclareAnnotation) declareDecl;
			String patternString = da.getPatternAsString();
			String annString = da.getAnnotationString();
			String kind = da.getKind().toString();
			annotation = AtAspectJAnnotationFactory.createDeclareAnnAnnotation(patternString, annString, kind,
					declarationSourceStart);
		} else if (declareDecl instanceof DeclareErrorOrWarning) {
			DeclareErrorOrWarning dd = (DeclareErrorOrWarning) declareDecl;
			annotation = AtAspectJAnnotationFactory.createDeclareErrorOrWarningAnnotation(dd.getPointcut().toString(),
					dd.getMessage(), dd.isError(), declarationSourceStart);
		} else if (declareDecl instanceof DeclareParents) {
			DeclareParents dp = (DeclareParents) declareDecl;
			String childPattern = dp.getChild().toString();
			Collection parentPatterns = dp.getParents().getExactTypes();
			StringBuilder parents = new StringBuilder();
			for (Iterator iter = parentPatterns.iterator(); iter.hasNext();) {
				UnresolvedType urt = iter.next();
				parents.append(urt.getName());
				if (iter.hasNext()) {
					parents.append(", ");
				}
			}
			annotation = AtAspectJAnnotationFactory.createDeclareParentsAnnotation(childPattern, parents.toString(),
					dp.isExtends(), declarationSourceStart);
		} else if (declareDecl instanceof DeclarePrecedence) {
			DeclarePrecedence dp = (DeclarePrecedence) declareDecl;
			String precedenceList = dp.getPatterns().toString();
			annotation = AtAspectJAnnotationFactory.createDeclarePrecedenceAnnotation(precedenceList, declarationSourceStart);
		} else if (declareDecl instanceof DeclareSoft) {
			DeclareSoft ds = (DeclareSoft) declareDecl;
			annotation = AtAspectJAnnotationFactory.createDeclareSoftAnnotation(ds.getPointcut().toString(), ds.getException()
					.getExactType().getName(), declarationSourceStart);
		}
		if (annotation != null) {
			AtAspectJAnnotationFactory.addAnnotation(this, annotation, this.scope);
		}
	}

	/**
	 * A declare declaration exists in a classfile only as an attibute on the class. Unlike advice and inter-type declarations, it
	 * has no corresponding method. **AMC** changed the above policy in the case of declare annotation, which uses a corresponding
	 * method as the anchor for the declared annotation
	 */
	public void generateCode(ClassScope classScope, ClassFile classFile) {
		if (shouldBeSynthetic()) {
			this.binding.modifiers |= Flags.AccSynthetic;
		}
		classFile.extraAttributes.add(new EclipseAttributeAdapter(new AjAttribute.DeclareAttribute(declareDecl)));
		if (shouldDelegateCodeGeneration()) {
			super.generateCode(classScope, classFile);
		}
		return;
	}

	protected boolean shouldDelegateCodeGeneration() {
		return true;
	}

	protected boolean shouldBeSynthetic() {
		return true;
	}

	public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
		// do nothing
	}

	public void resolveStatements(ClassScope upperScope) {
		// do nothing
	}

	// public boolean finishResolveTypes(SourceTypeBinding sourceTypeBinding) {
	// // there's nothing for our super to resolve usefully
	// //if (!super.finishResolveTypes(sourceTypeBinding)) return false;
	// // if (declare == null) return true;
	// //
	// // EclipseScope scope = new EclipseScope(new FormalBinding[0], this.scope);
	// //
	// // declare.resolve(scope);
	// // return true;
	// }

	public Declare build(ClassScope classScope) {
		if (declareDecl == null) {
			return null;
		}

		EclipseScope scope = new EclipseScope(FormalBinding.NONE, classScope);

		declareDecl.resolve(scope);
		return declareDecl;
	}

	public StringBuilder print(int tab, StringBuilder output) {
		printIndent(tab, output);
		if (declareDecl == null) {
			output.append("");
		} else {
			output.append(declareDecl.toString());
		}
		return output;
	}

	/**
	 * We need the ajc$declare method that is created to represent this declare to be marked as synthetic
	 */
	protected int generateInfoAttributes(ClassFile classFile) {
		return super.generateInfoAttributes(classFile, true);
	}

	public void postParse(TypeDeclaration typeDec) {
		super.postParse(typeDec);
		int declareSequenceNumberInType = ((AspectDeclaration) typeDec).declareCounter++;
		// FIXME asc the name should perhaps include the hashcode of the pattern (type/sig) for binary compatibility reasons!
		StringBuilder sb = new StringBuilder();
		sb.append("ajc$declare");
		// Declares can choose to provide a piece of the name - to enable
		// them to be easily distinguised at weave time (e.g. see declare annotation)
		if (declareDecl != null) {
			String suffix = declareDecl.getNameSuffix();
			if (suffix.length() != 0) {
				sb.append("_");
				sb.append(suffix);
			}
		}
		sb.append("_");
		sb.append(declareSequenceNumberInType);
		this.selector = sb.toString().toCharArray();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy