/** * Copyright (c) 2009-2011, The HATS Consortium. All rights reserved. * This file is licensed under the terms of the Modified BSD License. */ package abs.frontend.typechecker.ext; import abs.common.CompilerUtils; import abs.frontend.analyser.ErrorMessage; import abs.frontend.analyser.SemanticError; import abs.frontend.analyser.TypeError; import abs.frontend.ast.ASTNode; import abs.frontend.ast.AssignStmt; import abs.frontend.ast.ExpressionStmt; import abs.frontend.ast.Model; import abs.frontend.ast.NewExp; import abs.frontend.ast.PureExp; import abs.frontend.ast.Stmt; import abs.frontend.ast.VarDeclStmt; /** * @author rudi * * Checks for type correctness of `new' expression annotations. * - DC annotation must be of type ABS.DC.DeploymentComponent * * - DC annotation cannot be on `new local' expression * * - Deployment components cannot be created with `new local' * * - `HTTPName' annotation must be of type String */ public class NewExpressionChecker extends DefaultTypeSystemExtension { protected NewExpressionChecker(Model m) { super(m); } @Override public void checkExpressionStmt(ExpressionStmt expressionStmt) { checkDCCorrect(expressionStmt, CompilerUtils.getAnnotationValueFromName(expressionStmt.getAnnotations(), "ABS.DC.DC")); checkHTTPNameCorrect(expressionStmt, CompilerUtils.getAnnotationValueFromName(expressionStmt.getAnnotations(), "ABS.StdLib.HTTPName")); } @Override public void checkAssignStmt(AssignStmt s) { checkDCCorrect(s, CompilerUtils.getAnnotationValueFromName(s.getAnnotations(), "ABS.DC.DC")); checkHTTPNameCorrect(s, CompilerUtils.getAnnotationValueFromName(s.getAnnotations(), "ABS.StdLib.HTTPName")); } @Override public void checkVarDeclStmt(VarDeclStmt varDeclStmt) { checkDCCorrect(varDeclStmt, CompilerUtils.getAnnotationValueFromName(varDeclStmt.getAnnotations(), "ABS.DC.DC")); checkHTTPNameCorrect(varDeclStmt, CompilerUtils.getAnnotationValueFromName(varDeclStmt.getAnnotations(), "ABS.StdLib.HTTPName")); } private void checkDCCorrect(ASTNode<?> n, PureExp dc) { if (dc == null) return; if (!dc.getType().isDeploymentComponentType()) { errors.add(new TypeError(n, ErrorMessage.WRONG_DEPLOYMENT_COMPONENT, dc.getType().getQualifiedName())); } } private void checkHTTPNameCorrect(ASTNode<?> n, PureExp restname) { if (restname == null) return; if (!restname.getType().isStringType()) { errors.add(new TypeError(n, ErrorMessage.WRONG_HTTPNAME, restname.getType().getQualifiedName())); } } @Override public void checkNewExp(NewExp e) { if (e.hasLocal()) { if (e.getType().isDeploymentComponentType()) { // Don't create a deployment component with "new local" errors.add(new SemanticError(e, ErrorMessage.DEPLOYMENT_COMPONENT_NOT_COG, "dummy string to keep constructor happy")); } Stmt stmt = CompilerUtils.findStmtForExpression(e); if (stmt != null) { // should always be true if (CompilerUtils.getAnnotationValueFromName(stmt.getAnnotations(), "ABS.DC.DC") != null) { errors.add(new SemanticError(e, ErrorMessage.DEPLOYMENT_COMPONENT_IGNORED, "dummy string to keep constructor happy")); } } } } }