/******************************************************************************* * Copyright (c) 2008, 2017 xored software, Inc. and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * xored software, Inc. - initial API and Implementation (Andrei Sobolev) *******************************************************************************/ package org.eclipse.dltk.tcl.internal.validators.checks; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.Assert; import org.eclipse.dltk.core.IScriptProject; import org.eclipse.dltk.core.builder.ISourceLineTracker; import org.eclipse.dltk.tcl.ast.Node; import org.eclipse.dltk.tcl.ast.Script; import org.eclipse.dltk.tcl.ast.Substitution; import org.eclipse.dltk.tcl.ast.TclCommand; import org.eclipse.dltk.tcl.internal.validators.ICheckKinds; import org.eclipse.dltk.tcl.parser.ITclErrorReporter; import org.eclipse.dltk.tcl.parser.TclVisitor; import org.eclipse.dltk.tcl.validators.ITclCheck; public class UnreachableCodeCheck implements ITclCheck { public UnreachableCodeCheck() { } @Override public void checkCommands(final List<TclCommand> tclCommands, final ITclErrorReporter reporter, Map<String, String> options, IScriptProject project, ISourceLineTracker sourceLineTracker) { traverse(tclCommands, new TclVisitor() { private boolean check = true; private boolean error = false; @Override public boolean visit(TclCommand tclCommand) { Assert.isNotNull(tclCommand); if (!check) return false; if (error) { reporter.report(ICheckKinds.UNREACHABLE_CODE, "Unreachable code", null, tclCommand.getStart(), tclCommand.getEnd(), ITclErrorReporter.WARNING); error = check = false; return false; } else { if (tclCommand == null || tclCommand.getDefinition() == null) { return true; } if ("return".equals(tclCommand.getDefinition().getName())) { error = true; return false; } return true; } } @Override public void endVisit(TclCommand tclCommand) { Assert.isNotNull(tclCommand); if (tclCommand != null && tclCommand.getDefinition() != null && "return" .equals(tclCommand.getDefinition().getName())) { error = false; } check = true; } }); } public <T> void traverse(List<T> nodes, TclVisitor visitor) { for (int i = 0; i < nodes.size(); i++) { Node nde = (Node) nodes.get(i); if (nde instanceof Script) { Script script = (Script) nde; if (visitor.visit(script)) { traverse(script.getCommands(), visitor); int size = script.getCommands().size(); if (size != 0) visitor.endVisit(script.getCommands().get(size - 1)); } } else if (nde instanceof Substitution) { Substitution substitution = (Substitution) nde; if (visitor.visit(substitution)) { traverse(substitution.getCommands(), visitor); int size = substitution.getCommands().size(); if (size != 0) visitor.endVisit( substitution.getCommands().get(size - 1)); } } else if (nde instanceof TclCommand) { TclCommand command = (TclCommand) nde; if (visitor.visit(command)) { traverse(command.getArguments(), visitor); } } } } }