/*
* 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.common;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.nabucco.framework.generator.compiler.transformation.common.annotation.NabuccoAnnotationType;
import org.nabucco.framework.generator.compiler.transformation.java.common.basetype.BasetypeFacade;
import org.nabucco.framework.generator.compiler.verifier.error.VerificationErrorCriticality;
import org.nabucco.framework.generator.compiler.verifier.error.VerificationResult;
import org.nabucco.framework.generator.compiler.verifier.support.NabuccoTraversingVerifier;
import org.nabucco.framework.generator.parser.model.NabuccoModel;
import org.nabucco.framework.generator.parser.syntaxtree.BasetypeDeclaration;
import org.nabucco.framework.generator.parser.syntaxtree.DatatypeDeclaration;
import org.nabucco.framework.generator.parser.syntaxtree.EnumerationDeclaration;
import org.nabucco.framework.generator.parser.syntaxtree.ExtensionDeclaration;
import org.nabucco.framework.generator.parser.syntaxtree.MethodDeclaration;
import org.nabucco.framework.generator.parser.syntaxtree.NabuccoUnit;
import org.nabucco.framework.generator.parser.syntaxtree.Node;
import org.nabucco.framework.generator.parser.syntaxtree.NodeToken;
import org.nabucco.framework.generator.parser.syntaxtree.Parameter;
/**
* NabuccoMemberVerification to verify that a member name is only used once. and method signatures
* are unique.
*
* @author Silas Schwarz, PRODYNA AG
*/
public class NabuccoMemberVerification extends NabuccoTraversingVerifier {
private Set<String> names;
private static final String ERROR_MESASGE = "Duplicate member {0}";
private MessageFormat errorMessage = new MessageFormat(ERROR_MESASGE);
public NabuccoMemberVerification(String rootDir, String outDir) {
super(rootDir, outDir);
}
@Override
public void visit(NabuccoUnit n, VerificationResult argu) {
names = new HashSet<String>();
super.visit(n, argu);
}
@Override
public void visit(BasetypeDeclaration n, VerificationResult argu) {
if (!getAnnotationMapper().hasAnnotation(n.annotationDeclaration,
NabuccoAnnotationType.REDEFINED)) {
check(n.nodeToken3, argu);
}
super.visit(n, argu);
}
@Override
public void visit(DatatypeDeclaration n, VerificationResult argu) {
if (!getAnnotationMapper().hasAnnotation(n.annotationDeclaration,
NabuccoAnnotationType.REDEFINED)) {
check(n.nodeToken2, argu);
}
super.visit(n, argu);
}
@Override
public void visit(EnumerationDeclaration n, VerificationResult argu) {
if (!getAnnotationMapper().hasAnnotation(n.annotationDeclaration,
NabuccoAnnotationType.REDEFINED)) {
check(n.nodeToken2, argu);
}
;
super.visit(n, argu);
}
@Override
public void visit(MethodDeclaration n, VerificationResult argu) {
StringBuffer sb = new StringBuffer();
NodeToken checkedToken = n.nodeToken1;
sb.append(n.nodeToken1.tokenImage);
sb.append("(");
if (n.parameterList != null
&& n.parameterList.nodeListOptional != null
&& n.parameterList.nodeListOptional.present()) {
Iterator<Node> iterator = n.parameterList.nodeListOptional.nodes.iterator();
// can only contain instances of Parameter...
while (iterator.hasNext()) {
Node next = iterator.next();
if (next instanceof Parameter) {
Parameter asParam = (Parameter) next;
if (asParam.nodeToken != null) {
sb.append((asParam).nodeToken.tokenImage);
}
}
if (iterator.hasNext()) {
sb.append(", ");
}
}
}
sb.append(")");
checkedToken = new NodeToken(sb.toString(), checkedToken.kind, checkedToken.beginLine,
checkedToken.beginColumn, checkedToken.endLine, checkedToken.endColumn);
check(checkedToken, argu);
super.visit(n, argu);
}
@Override
public void visit(ExtensionDeclaration n, VerificationResult argu) {
Node choice = n.nodeChoice.choice;
if (choice instanceof NodeToken) {
String tokenImage = ((NodeToken) choice).tokenImage;
if (!BasetypeFacade.isBasetype(tokenImage)) {
NabuccoModel resolvedModel = resolveModel(tokenImage);
if (resolvedModel != null
&& resolvedModel.getUnit() != null
&& resolvedModel.getUnit().nabuccoStatement != null) {
// set package
resolvedModel.getUnit().packageDeclaration.accept(this, argu);
// gather imports [NBC-1305]
resolvedModel.getUnit().nodeListOptional.accept(this, argu);
// sub visit
resolvedModel.getUnit().nabuccoStatement.accept(this, argu);
}
}
}
super.visit(n, argu);
}
private void check(NodeToken token, VerificationResult result) {
if (!names.add(token.tokenImage)) {
result.addError(VerificationErrorCriticality.ERROR, token.beginLine, token.endLine,
token.beginColumn, token.endColumn,
errorMessage.format(new Object[] { token.tokenImage }));
}
}
}