/* * #%~ * The VDM Type Checker * %% * Copyright (C) 2008 - 2014 Overture * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #~% */ package org.overture.typechecker.utilities.expression; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.Vector; import org.overture.ast.analysis.AnalysisException; import org.overture.ast.analysis.QuestionAnswerAdaptor; import org.overture.ast.definitions.AUntypedDefinition; import org.overture.ast.definitions.PDefinition; import org.overture.ast.factory.AstFactory; import org.overture.ast.intf.lex.ILexNameToken; import org.overture.ast.modules.AAllExport; import org.overture.ast.modules.AFunctionExport; import org.overture.ast.modules.AOperationExport; import org.overture.ast.modules.ATypeExport; import org.overture.ast.modules.AValueExport; import org.overture.ast.node.INode; import org.overture.ast.typechecker.NameScope; import org.overture.ast.types.AFieldField; import org.overture.ast.types.ANamedInvariantType; import org.overture.ast.types.ARecordInvariantType; import org.overture.ast.types.PType; import org.overture.ast.types.SInvariantType; import org.overture.typechecker.assistant.ITypeCheckerAssistantFactory; /** * Used to find the definition of an exported expression from its actualType. * * @author kel */ public class ExportDefinitionFinder extends QuestionAnswerAdaptor<LinkedList<PDefinition>, Collection<? extends PDefinition>> { protected ITypeCheckerAssistantFactory af; public ExportDefinitionFinder(ITypeCheckerAssistantFactory af) { this.af = af; } @Override public Collection<? extends PDefinition> caseAAllExport(AAllExport exp, LinkedList<PDefinition> actualDefs) throws AnalysisException { return actualDefs; // The lot! } @Override public Collection<? extends PDefinition> caseAFunctionExport( AFunctionExport exp, LinkedList<PDefinition> actualDefs) throws AnalysisException { List<PDefinition> list = new Vector<PDefinition>(); for (ILexNameToken name : exp.getNameList()) { PDefinition def = af.createPDefinitionListAssistant().findName(actualDefs, name, NameScope.NAMES); if (def != null) { list.add(def); } } return list; } @Override public Collection<? extends PDefinition> caseAOperationExport( AOperationExport exp, LinkedList<PDefinition> actualDefs) throws AnalysisException { List<PDefinition> list = new Vector<PDefinition>(); for (ILexNameToken name : ((AOperationExport) exp).getNameList()) { PDefinition def = af.createPDefinitionListAssistant().findName(actualDefs, name, NameScope.NAMES); if (def != null) { list.add(def); } } return list; } @Override public Collection<? extends PDefinition> caseATypeExport(ATypeExport exp, LinkedList<PDefinition> actualDefs) throws AnalysisException { ILexNameToken name = ((ATypeExport) exp).getName(); List<PDefinition> list = new Vector<PDefinition>(); PDefinition def = af.createPDefinitionListAssistant().findType(actualDefs, name, name.getModule()); if (def != null) { if (exp.getStruct()) { list.add(def); } else { PType type = af.createPDefinitionAssistant().getType(def); if (type instanceof ANamedInvariantType) { ANamedInvariantType ntype = (ANamedInvariantType) type; SInvariantType copy = AstFactory.newANamedInvariantType(ntype.getName().clone(), ntype.getType()); // new ANamedInvariantType(ntype.getName().getLocation(),false,list, false, null, // ntype.getName().clone(), ntype.getType()); copy.setOpaque(true); copy.setInvDef(ntype.getInvDef()); list.add(AstFactory.newATypeDefinition(def.getName(), copy, null, null)); // list.add(new ATypeDefinition(def.getName().location, // NameScope.TYPENAME,false,null,PAccessSpecifierAssistant.getDefault(),null, copy, // null,null,null,false,def.getName())); } else if (type instanceof ARecordInvariantType) { ARecordInvariantType rtype = (ARecordInvariantType) type; @SuppressWarnings("unchecked") SInvariantType copy = AstFactory.newARecordInvariantType(rtype.getName().clone(), (List<AFieldField>) rtype.getFields().clone()); // new ARecordInvariantType(rtype.getName().location,false, rtype.getName().clone(), (List<? // extends AFieldField>) rtype.getFields().clone()); copy.setOpaque(true); copy.setInvDef(rtype.getInvDef()); list.add(AstFactory.newATypeDefinition(def.getName(), copy, null, null)); // new ATypeDefinition(def.getName().location, // NameScope.TYPENAME,false,null,PAccessSpecifierAssistant.getDefault(),null, // copy,null,null,null,false,def.getName())); } } } return list; } @Override public Collection<? extends PDefinition> caseAValueExport(AValueExport exp, LinkedList<PDefinition> actualDefs) throws AnalysisException { List<PDefinition> list = new Vector<PDefinition>(); for (ILexNameToken name : exp.getNameList()) { PDefinition def = af.createPDefinitionListAssistant().findName(actualDefs, name, NameScope.NAMES); PType type = exp.getExportType().clone(); if (def != null) { if (def instanceof AUntypedDefinition) { AUntypedDefinition untyped = (AUntypedDefinition) def; list.add(AstFactory.newALocalDefinition(untyped.getLocation(), untyped.getName(), NameScope.GLOBAL, type)); // new ALocalDefinition(untyped.getLocation(), NameScope.GLOBAL, // false,null,PAccessSpecifierAssistant.getDefault(),type, false,untyped.getName())); } else { list.add(def); } } } return list; } @Override public Collection<? extends PDefinition> createNewReturnValue(INode node, LinkedList<PDefinition> question) throws AnalysisException { assert false;// "No match in switch"; return null; } @Override public Collection<? extends PDefinition> createNewReturnValue(Object node, LinkedList<PDefinition> question) throws AnalysisException { assert false;// "No match in switch"; return null; } }