#710 Deferring processing of mappers with incomplete source/target types to a later processing round

This commit is contained in:
Gunnar Morling 2015-12-17 23:29:56 +01:00
parent 03bf027858
commit 55b74ae384
15 changed files with 619 additions and 28 deletions

View File

@ -0,0 +1,34 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.itest.tests;
import org.junit.runner.RunWith;
import org.mapstruct.itest.testutil.runner.ProcessorSuite;
import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType;
import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner;
/**
* Tests usage of MapStruct with another processor that generates supertypes of mapping source/target types.
*
* @author Gunnar Morling
*/
@RunWith( ProcessorSuiteRunner.class )
@ProcessorSuite(baseDir = "superTypeGenerationTest", processorTypes = ProcessorType.ORACLE_JAVA_8)
public class SuperTypeGenerationTest {
}

View File

@ -0,0 +1,39 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.mapstruct.itest</groupId>
<artifactId>itest-supertypegeneration-aggregator</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>itest-supertypegeneration-generator</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgs>
<compilerArg>-proc:none</compilerArg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,88 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.itest.supertypegeneration;
import java.io.IOException;
import java.io.Writer;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.tools.JavaFileObject;
/**
* Generates base classes.
*
* @author Gunnar Morling
*
*/
@SupportedAnnotationTypes("org.mapstruct.itest.supertypegeneration.GenBase")
public class BaseGenerationProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement annotation : annotations) {
Set<? extends Element> annotated = roundEnv.getElementsAnnotatedWith( annotation );
for (Element element : annotated) {
AnnotationMirror annotationMirror = element.getAnnotationMirrors().get(0);
Integer level = (Integer) annotationMirror.getElementValues().values().iterator().next().getValue();
if ( level >= 1 ) {
try {
PackageElement packageElement = processingEnv.getElementUtils().getPackageOf( element );
Name name = element.getSimpleName();
String baseName = name.toString() + "Base";
String baseBaseName = level > 1 ? baseName + "Base" : null;
JavaFileObject baseGen = processingEnv.getFiler().createSourceFile( packageElement.getQualifiedName() + "." + baseName );
Writer writer = baseGen.openWriter();
writer.append( "package " + packageElement.getQualifiedName() + ";\n" );
writer.append( "\n" );
writer.append( "import org.mapstruct.itest.supertypegeneration.GenBase;\n" );
writer.append( "\n" );
if ( level > 1 ) {
writer.append( "@GenBase( " + (level - 1) + " )\n" );
writer.append( "public class " + baseName + " extends " + baseBaseName + " {\n" );
}
else {
writer.append( "public class " + baseName + " {\n" );
}
writer.append( " private String baseName" + level + ";\n" );
writer.append( " public String getBaseName" + level + "() { return baseName" + level + "; }\n" );
writer.append( " public void setBaseName" + level + "(String baseName" + level + ") { this.baseName" + level + " = baseName" + level + ";}\n" );
writer.append( "}\n" );
writer.flush();
writer.close();
}
catch (IOException e) {
throw new RuntimeException( e );
}
}
}
}
return false;
}
}

View File

@ -0,0 +1,30 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.itest.supertypegeneration;
/**
* Triggers generation of base-classes.
*
* @author Gunnar Morling
*
*/
public @interface GenBase {
int value();
}

View File

@ -0,0 +1,17 @@
# Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
# and/or other contributors as indicated by the @authors tag. See the
# copyright.txt file in the distribution for a full listing of all
# contributors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
org.mapstruct.itest.supertypegeneration.BaseGenerationProcessor

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
and/or other contributors as indicated by the @authors tag. See the
copyright.txt file in the distribution for a full listing of all
contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-it-parent</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>org.mapstruct.itest</groupId>
<artifactId>itest-supertypegeneration-aggregator</artifactId>
<packaging>pom</packaging>
<modules>
<module>generator</module>
<module>usage</module>
</modules>
</project>

View File

@ -0,0 +1,47 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.mapstruct.itest</groupId>
<artifactId>itest-supertypegeneration-aggregator</artifactId>
<version>1.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>itest-supertypegeneration-usage</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mapstruct.itest</groupId>
<artifactId>itest-supertypegeneration-generator</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgs>
<compilerArg>-XprintProcessorInfo</compilerArg>
<compilerArg>-XprintRounds</compilerArg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,35 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.itest.supertypegeneration.usage;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
*
* @author Gunnar Morling
*
*/
@Mapper
public abstract class AnotherOrderMapper {
public static final AnotherOrderMapper INSTANCE = Mappers.getMapper( AnotherOrderMapper.class );
public abstract OrderDto orderToDto(Order order);
}

View File

@ -0,0 +1,38 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.itest.supertypegeneration.usage;
import org.mapstruct.itest.supertypegeneration.GenBase;
/**
* @author Gunnar Morling
*/
@GenBase(2)
public class Order extends OrderBase {
private String item;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
}

View File

@ -0,0 +1,38 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.itest.supertypegeneration.usage;
import org.mapstruct.itest.supertypegeneration.GenBase;
/**
* @author Gunnar Morling
*/
@GenBase(2)
public class OrderDto extends OrderDtoBase {
private String item;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
}

View File

@ -0,0 +1,35 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.itest.supertypegeneration.usage;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
*
* @author Gunnar Morling
*
*/
@Mapper
public abstract class OrderMapper {
public static final OrderMapper INSTANCE = Mappers.getMapper( OrderMapper.class );
public abstract OrderDto orderToDto(Order order);
}

View File

@ -0,0 +1,54 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.itest.supertypegeneration.usage;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.mapstruct.itest.supertypegeneration.usage.Order;
import org.mapstruct.itest.supertypegeneration.usage.OrderDto;
import org.mapstruct.itest.supertypegeneration.usage.OrderMapper;
/**
* Integration test for using MapStruct with another annotation processor that generates super-types of mapping source
* and target types.
*
* @author Gunnar Morling
*/
public class GeneratedBasesTest {
@Test
public void considersPropertiesOnGeneratedSourceAndTargetTypes() {
Order order = new Order();
order.setItem( "my item" );
order.setBaseName2( "my base name 2" );
order.setBaseName1( "my base name 1" );
OrderDto dto = OrderMapper.INSTANCE.orderToDto( order );
assertEquals( order.getItem(), dto.getItem() );
assertEquals( order.getBaseName2(), dto.getBaseName2() );
assertEquals( order.getBaseName1(), dto.getBaseName1() );
// Let's make sure several mappers can be generated
dto = AnotherOrderMapper.INSTANCE.orderToDto( order );
assertEquals( order.getItem(), dto.getItem() );
assertEquals( order.getBaseName2(), dto.getBaseName2() );
assertEquals( order.getBaseName1(), dto.getBaseName1() );
}
}

View File

@ -23,6 +23,7 @@ import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
@ -49,6 +50,7 @@ import org.mapstruct.ap.internal.processor.DefaultModelElementProcessorContext;
import org.mapstruct.ap.internal.processor.ModelElementProcessor;
import org.mapstruct.ap.internal.processor.ModelElementProcessor.ProcessorContext;
import org.mapstruct.ap.internal.util.AnnotationProcessingException;
import org.mapstruct.ap.internal.util.TypeHierarchyErroneousException;
/**
* A JSR 269 annotation {@link Processor} which generates the implementations for mapper interfaces (interfaces
@ -105,6 +107,17 @@ public class MappingProcessor extends AbstractProcessor {
private Options options;
/**
* Any mappers for which an implementation cannot be generated in the current round because they have source/target
* types with incomplete hierarchies (as super-types are to be generated by other processors). They will be
* processed in subsequent rounds.
* <p>
* If the hierarchy of a mapper's source/target types is never completed (i.e. the missing super-types are not
* generated by other processors), this mapper will not be generated; That's fine, the compiler will raise an error
* due to the inconsistent Java types used as source or target anyways.
*/
private Set<TypeElement> deferredMappers = new HashSet<TypeElement>();
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init( processingEnv );
@ -132,41 +145,79 @@ public class MappingProcessor extends AbstractProcessor {
@Override
public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnvironment) {
// nothing to do in the last round
if ( !roundEnvironment.processingOver() ) {
// process any mappers left over from previous rounds
Set<TypeElement> deferredMappers = getAndResetDeferredMappers();
processMapperElements( deferredMappers );
// get and process any mappers from this round
Set<TypeElement> mappers = getMappers( annotations, roundEnvironment );
processMapperElements( mappers );
}
return ANNOTATIONS_CLAIMED_EXCLUSIVELY;
}
/**
* Gets fresh copies of all mappers deferred from previous rounds (the originals may contain references to
* erroneous source/target type elements).
*/
private Set<TypeElement> getAndResetDeferredMappers() {
Set<TypeElement> deferred = new HashSet<TypeElement>( deferredMappers.size() );
for (TypeElement element : deferredMappers ) {
deferred.add( processingEnv.getElementUtils().getTypeElement( element.getQualifiedName() ) );
}
deferredMappers.clear();
return deferred;
}
private Set<TypeElement> getMappers(final Set<? extends TypeElement> annotations,
final RoundEnvironment roundEnvironment) {
Set<TypeElement> mapperTypes = new HashSet<TypeElement>();
for ( TypeElement annotation : annotations ) {
//Indicates that the annotation's type isn't on the class path of the compiled
//project. Let the compiler deal with that and print an appropriate error.
if ( annotation.getKind() != ElementKind.ANNOTATION_TYPE ) {
continue;
}
Set<? extends Element> elementsWithAnnotation;
try {
elementsWithAnnotation = roundEnvironment.getElementsAnnotatedWith( annotation );
Set<? extends Element> annotatedMappers = roundEnvironment.getElementsAnnotatedWith( annotation );
for (Element mapperElement : annotatedMappers) {
TypeElement mapperTypeElement = asTypeElement( mapperElement );
// on some JDKs, RoundEnvironment.getElementsAnnotatedWith( ... ) returns types with
// annotations unknown to the compiler, even though they are not declared Mappers
if ( mapperTypeElement != null && MapperPrism.getInstanceOn( mapperTypeElement ) != null ) {
mapperTypes.add( mapperTypeElement );
}
}
}
catch ( Throwable t ) { // whenever that may happen, but just to stay on the save side
handleUncaughtError( annotation, t );
continue;
}
for ( Element mapperElement : elementsWithAnnotation ) {
try {
TypeElement mapperTypeElement = asTypeElement( mapperElement );
// on some JDKs, RoundEnvironment.getElementsAnnotatedWith( ... ) returns types with
// annotations unknown to the compiler, even though they are not declared Mappers
if ( mapperTypeElement == null || MapperPrism.getInstanceOn( mapperTypeElement ) == null ) {
continue;
}
return mapperTypes;
}
private void processMapperElements(Set<TypeElement> mapperElements) {
for ( TypeElement mapperElement : mapperElements ) {
try {
// create a new context for each generated mapper in order to have imports of referenced types
// correctly managed;
// note that this assumes that a new source file is created for each mapper which must not
// necessarily be the case, e.g. in case of several mapper interfaces declared as inner types
// of one outer interface
ProcessorContext context = new DefaultModelElementProcessorContext( processingEnv, options );
processMapperTypeElement( context, mapperTypeElement );
processMapperTypeElement( context, mapperElement );
}
catch ( TypeHierarchyErroneousException thie ) {
deferredMappers.add( mapperElement );
}
catch ( Throwable t ) {
handleUncaughtError( mapperElement, t );
@ -175,9 +226,6 @@ public class MappingProcessor extends AbstractProcessor {
}
}
return ANNOTATIONS_CLAIMED_EXCLUSIVELY;
}
private void handleUncaughtError(Element element, Throwable thrown) {
StringWriter sw = new StringWriter();
thrown.printStackTrace( new PrintWriter( sw ) );

View File

@ -155,6 +155,10 @@ public class Executables {
element = replaceTypeElementIfNecessary( elementUtils, element );
}
if ( element.asType().getKind() == TypeKind.ERROR ) {
throw new TypeHierarchyErroneousException( element );
}
addNotYetOverridden( elementUtils, alreadyAdded, methodsIn( element.getEnclosedElements() ), parentType );
if ( hasNonObjectSuperclass( element ) ) {
@ -244,8 +248,12 @@ public class Executables {
* @return {@code true}, iff the type has a super-class that is not java.lang.Object
*/
private static boolean hasNonObjectSuperclass(TypeElement element) {
if ( element.getSuperclass().getKind() == TypeKind.ERROR ) {
throw new TypeHierarchyErroneousException( element );
}
return element.getSuperclass().getKind() == TypeKind.DECLARED
&& asTypeElement( element.getSuperclass() ).getSuperclass().getKind() == TypeKind.DECLARED;
&& !asTypeElement( element.getSuperclass() ).getQualifiedName().toString().equals( "java.lang.Object" );
}
/**

View File

@ -0,0 +1,40 @@
/**
* Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/)
* and/or other contributors as indicated by the @authors tag. See the
* copyright.txt file in the distribution for a full listing of all
* contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mapstruct.ap.internal.util;
import javax.lang.model.element.TypeElement;
/**
* Indicates a type element was visited whose hierarchy was erroneous, because it has a non-existing super-type.
*
* @author Gunnar Morling
*
*/
public class TypeHierarchyErroneousException extends RuntimeException {
private TypeElement element;
public TypeHierarchyErroneousException(TypeElement element) {
this.element = element;
}
public TypeElement getElement() {
return element;
}
}