/* * Copyright 2012 PRODYNA AG * * Licensed under the Eclipse Public License (EPL), Version 1.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.opensource.org/licenses/eclipse-1.0.php or * http://www.nabucco.org/License.html * * 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.nabucco.framework.generator.compiler.verifier.datatype; import java.util.Iterator; import org.nabucco.framework.generator.compiler.transformation.common.annotation.NabuccoAnnotationMapper; import org.nabucco.framework.generator.compiler.transformation.common.annotation.NabuccoAnnotationType; import org.nabucco.framework.generator.compiler.verifier.NabuccoModelVerificationVisitor; import org.nabucco.framework.generator.compiler.verifier.error.VerificationErrorCriticality; import org.nabucco.framework.generator.compiler.verifier.error.VerificationResult; import org.nabucco.framework.generator.parser.syntaxtree.AnnotationDeclaration; import org.nabucco.framework.generator.parser.syntaxtree.BasetypeDeclaration; import org.nabucco.framework.generator.parser.syntaxtree.DatatypeDeclaration; import org.nabucco.framework.generator.parser.syntaxtree.DatatypeStatement; import org.nabucco.framework.generator.parser.syntaxtree.EnumerationDeclaration; import org.nabucco.framework.generator.parser.syntaxtree.ExtensionDeclaration; import org.nabucco.framework.generator.parser.syntaxtree.Node; import org.nabucco.framework.generator.parser.syntaxtree.NodeToken; /** * NabuccoRedefineSubclass * * @author Silas Schwarz, PRODYNA AG */ public class NabuccoRedefineSubclass extends NabuccoModelVerificationVisitor { private static final String NABUCCO_DATATYPE = "NabuccoDatatype"; private DatatypeStatement current; private NabuccoAnnotationMapper mapper = NabuccoAnnotationMapper.getInstance(); @Override public void visit(DatatypeStatement n, VerificationResult argu) { this.current = n; super.visit(n, argu); this.current = null; } @Override public void visit(BasetypeDeclaration n, VerificationResult argu) { if (mapper.hasAnnotation(n.annotationDeclaration, NabuccoAnnotationType.REDEFINED) && subclassCheck()) { complain(n.annotationDeclaration, argu); } super.visit(n, argu); } @Override public void visit(DatatypeDeclaration n, VerificationResult argu) { if (mapper.hasAnnotation(n.annotationDeclaration, NabuccoAnnotationType.REDEFINED) && subclassCheck()) { complain(n.annotationDeclaration, argu); } super.visit(n, argu); } @Override public void visit(EnumerationDeclaration n, VerificationResult argu) { if (mapper.hasAnnotation(n.annotationDeclaration, NabuccoAnnotationType.REDEFINED) && subclassCheck()) { complain(n.annotationDeclaration, argu); } super.visit(n, argu); } private void complain(AnnotationDeclaration annotationDeclaration, VerificationResult result) { Iterator<Node> iterator = annotationDeclaration.nodeListOptional.nodes.iterator(); while (iterator.hasNext()) { Node next = iterator.next(); NodeToken token = (NodeToken) next; if (token.tokenImage.compareTo(NabuccoAnnotationType.REDEFINED.getName()) == 0) { result.addError(VerificationErrorCriticality.WARNING, token.beginLine, token.endLine, token.beginColumn, token.endColumn, "Illegal use of @Redefine Annotation, not subclassing"); } } } private boolean subclassCheck() { if (current == null) { return false; } if (!current.nodeOptional1.present()) { return true; } else if (current.nodeOptional1.node instanceof ExtensionDeclaration) { ExtensionDeclaration node = (ExtensionDeclaration) current.nodeOptional1.node; NodeToken tokenImage = (NodeToken) node.nodeChoice.choice; String superType = tokenImage.tokenImage; if (superType.isEmpty() || superType.endsWith(NABUCCO_DATATYPE)) { return true; } } return false; } }