/* * #%~ * org.overture.ide.debug * %% * 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.ide.debug.ui.launchconfigurations; import java.util.Arrays; import java.util.List; import java.util.Vector; import org.eclipse.jface.operation.IRunnableContext; import org.overture.ast.definitions.AClassClassDefinition; import org.overture.ast.definitions.AExplicitFunctionDefinition; import org.overture.ast.definitions.AExplicitOperationDefinition; import org.overture.ast.modules.AModuleModules; import org.overture.ast.node.INode; import org.overture.ast.statements.ASubclassResponsibilityStm; import org.overture.typechecker.assistant.ITypeCheckerAssistantFactory; import org.overture.typechecker.assistant.TypeCheckerAssistantFactory; import org.overture.typechecker.assistant.pattern.PatternListTC; public class MethodSearchEngine { public final ITypeCheckerAssistantFactory assistantFactory = new TypeCheckerAssistantFactory(); public final static int MAIN_ONLY = 1; public final static int EXPLICIT_FUNCTION = 2; public final static int EXPLICIT_OPERATION = 4; public final static int STATIC = 8; public final static int PUBLIC = 16; public static final int WORLD_CLASS = 32; public static final int RUN = 64; public INode[] searchMainMethods(IRunnableContext context, Object[] nodes, int constraints) { boolean onlyMain = (constraints & MAIN_ONLY) == MAIN_ONLY; boolean onlyExplicitFunction = (constraints & EXPLICIT_FUNCTION) == EXPLICIT_FUNCTION; boolean onlyExplicitOperation = (constraints & EXPLICIT_OPERATION) == EXPLICIT_OPERATION; boolean onlyStatic = (constraints & STATIC) == STATIC; boolean onlyPublicAccess = (constraints & PUBLIC) == PUBLIC; boolean onlyRun = (constraints & RUN) == RUN; boolean onlyWorldClass = (constraints & WORLD_CLASS) == WORLD_CLASS; final String MAIN_NAME = "main"; final String RUN_NAME = "run"; final String WORLD_NAME = "world"; List<INode> matched = new Vector<INode>(); for (int i = 0; i < nodes.length; i++) { Object iAstNode = nodes[i]; boolean accept = false; if (onlyExplicitOperation && iAstNode instanceof AExplicitOperationDefinition) { AExplicitOperationDefinition exop = (AExplicitOperationDefinition) iAstNode; if (isConstructor(exop)) { continue;// is constructor } if (onlyRun && !exop.getName().getSimpleName().equalsIgnoreCase(RUN_NAME)) { continue; } if (onlyWorldClass && (exop.getClassDefinition() == null || !exop.getClassDefinition().getName().getSimpleName().equalsIgnoreCase(WORLD_NAME))) { continue; } if (onlyStatic && !assistantFactory.createPAccessSpecifierAssistant().isStatic(exop.getAccess())) { continue; } if (!assistantFactory.createPAccessSpecifierAssistant().isStatic(exop.getAccess()) && exop.getClassDefinition() != null) { // check for empty constructor boolean ok = false; boolean constructorFound = false; for (Object def : exop.getClassDefinition().getDefinitions()) { if (def instanceof AExplicitOperationDefinition) { AExplicitOperationDefinition ctor = (AExplicitOperationDefinition) def; if (isConstructor(ctor)) { continue; } if (ctor.getName().getSimpleName().equalsIgnoreCase(exop.getClassDefinition().getName().getSimpleName())) { constructorFound = true; } if (ctor.getBody() instanceof ASubclassResponsibilityStm) { // abstract class instantiation impossible ok = false; break; } if (ctor.getParameterPatterns() != null && ctor.getParameterPatterns().size() > 0) { ok = true; break; } } } if (!ok && constructorFound) { continue; } } if (onlyMain && !exop.getName().getSimpleName().toLowerCase().equals(MAIN_NAME)) { continue; } if (onlyPublicAccess && !assistantFactory.createPAccessSpecifierAssistant().isPublic(exop.getAccess())) { continue; } if (exop.getParameterPatterns() != null && exop.getParameterPatterns().size() > 0) { continue; } accept = true; } if (onlyExplicitFunction && iAstNode instanceof AExplicitFunctionDefinition) { AExplicitFunctionDefinition exfu = (AExplicitFunctionDefinition) iAstNode; if (onlyStatic && !assistantFactory.createPAccessSpecifierAssistant().isStatic(exfu.getAccess())) { continue; } if (onlyRun && !exfu.getName().getSimpleName().equalsIgnoreCase(RUN_NAME)) { continue; } if (onlyWorldClass && (exfu.getClassDefinition() == null || !exfu.getClassDefinition().getName().getSimpleName().equalsIgnoreCase(WORLD_NAME))) { continue; } if (onlyMain && !exfu.getName().getSimpleName().toLowerCase().equals(MAIN_NAME)) { continue; } if (onlyPublicAccess && !assistantFactory.createPAccessSpecifierAssistant().isPublic(exfu.getAccess())) { continue; } if (exfu.getParamPatternList() != null && exfu.getParamPatternList().size() > 0 && exfu.getParamPatternList().get(0) instanceof PatternListTC && ((PatternListTC) exfu.getParamPatternList().get(0)).size() > 0) { continue; } accept = true; } if (accept && iAstNode instanceof INode) { matched.add((INode) iAstNode); } if (iAstNode instanceof AClassClassDefinition) { Object[] elements = ((AClassClassDefinition) iAstNode).getDefinitions().toArray(); matched.addAll(Arrays.asList(searchMainMethods(context, elements, constraints))); } if (iAstNode instanceof AModuleModules) { Object[] elements = ((AModuleModules) iAstNode).getDefs().toArray(); matched.addAll(Arrays.asList(searchMainMethods(context, elements, constraints))); } } return matched.toArray(new INode[matched.size()]); } public static boolean isConstructor(AExplicitOperationDefinition op) { if (op.getIsConstructor() || op.getClassDefinition() != null && op.getName().getSimpleName().equalsIgnoreCase(op.getClassDefinition().getLocation().getModule())) { return true; } return false; } }