/** * 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. * * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. */ /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.thingml.compilers.checker.genericRules; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.sintef.thingml.*; import org.sintef.thingml.constraints.ThingMLHelpers; import org.sintef.thingml.constraints.Types; import org.sintef.thingml.helpers.ActionHelper; import org.sintef.thingml.helpers.ConfigurationHelper; import org.sintef.thingml.helpers.ThingHelper; import org.sintef.thingml.helpers.TyperHelper; import org.thingml.compilers.checker.Checker; import org.thingml.compilers.checker.Rule; import java.util.ArrayList; import java.util.List; /** * * @author sintef */ public class VariableUsage extends Rule { public VariableUsage() { super(); } @Override public Checker.InfoType getHighestLevel() { return Checker.InfoType.NOTICE; } @Override public String getName() { return "Messages Usage"; } @Override public String getDescription() { return "Check variables and properties."; } private void check(Variable va, Expression e, Thing t, Checker checker, EObject o) { if (va.getCardinality() == null) {//TODO: check arrays if (va instanceof Property) { Property p = (Property) va; if (!p.isChangeable()) { checker.addGenericError("Property " + va.getName() + " of Thing " + t.getName() + " is read-only and cannot be re-assigned.", o); } } /*if (va.getType() == null) {//parsing probably still ongoing...v checker.addGenericError("Property " + va.getName() + " of Thing " + t.getName() + " has no type", va); return; }*/ if (!(va.getType() == null)) { final Type expected = TyperHelper.getBroadType(va.getType()); final Type actual = checker.typeChecker.computeTypeOf(e); if (actual != null) { //FIXME: improve type checker so that it does not return null (some actions are not yet implemented in the type checker) if (actual.equals(Types.ERROR_TYPE)) { checker.addGenericError("Property " + va.getName() + " of Thing " + t.getName() + " is assigned with an erroneous value/expression. Expected " + TyperHelper.getBroadType(expected).getName() + ", assigned with " + TyperHelper.getBroadType(actual).getName(), o); } else if (actual.equals(Types.ANY_TYPE)) { checker.addGenericWarning("Property " + va.getName() + " of Thing " + t.getName() + " is assigned with a value/expression which cannot be typed.", o); } else if (!TyperHelper.isA(actual, expected)) { checker.addGenericError("Property " + va.getName() + " of Thing " + t.getName() + " is assigned with an erroneous value/expression. Expected " + TyperHelper.getBroadType(expected).getName() + ", assigned with " + TyperHelper.getBroadType(actual).getName(), o); } } } } } @Override public void check(ThingMLModel model, Checker checker) { for (Thing t : ThingMLHelpers.allThings(model)) { check(t, checker); } } @Override public void check(Configuration cfg, Checker checker) { for (Thing t : ConfigurationHelper.allThings(cfg)) { check(t, checker); } } private void check(Thing t, Checker checker) { for (Action a : ActionHelper.getAllActions(t, VariableAssignment.class)) { //FIXME @Brice see testIfElse if (a instanceof VariableAssignment) { VariableAssignment va = (VariableAssignment) a; if (va.getExpression() != null) check(va.getProperty(), va.getExpression(), t, checker, va); } } for (Action a : ActionHelper.getAllActions(t, LocalVariable.class)) { //FIXME @Brice see testIfElse if (a instanceof LocalVariable) { LocalVariable lv = (LocalVariable) a; if (lv.getInit() != null) check(lv, lv.getInit(), t, checker, lv); } } for(Property p : ThingHelper.allPropertiesInDepth(t)) { boolean isUsed = false; for(Property pr : ThingHelper.allUsedProperties(t)) { if (EcoreUtil.equals(p, pr)) { isUsed = true; break; } } if (!isUsed) { checker.addGenericWarning("Property " + p.getName() + " of Thing " + t.getName() + " is never used. Consider removing (or using) it.", p); } } } }