package loo1.plp.orientadaObjetos1.comando; import loo1.plp.expressions2.memory.VariavelJaDeclaradaException; import loo1.plp.expressions2.memory.VariavelNaoDeclaradaException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ClasseJaDeclaradaException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ClasseNaoDeclaradaException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ObjetoJaDeclaradoException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ObjetoNaoDeclaradoException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ProcedimentoJaDeclaradoException; import loo1.plp.orientadaObjetos1.excecao.declaracao.ProcedimentoNaoDeclaradoException; import loo1.plp.orientadaObjetos1.excecao.execucao.EntradaInvalidaException; import loo1.plp.orientadaObjetos1.expressao.Expressao; import loo1.plp.orientadaObjetos1.expressao.ListaExpressao; import loo1.plp.orientadaObjetos1.expressao.leftExpression.Id; import loo1.plp.orientadaObjetos1.expressao.valor.ValorRef; import loo1.plp.orientadaObjetos1.memoria.AmbienteCompilacaoOO1; import loo1.plp.orientadaObjetos1.memoria.AmbienteExecucaoOO1; import loo1.plp.orientadaObjetos1.memoria.ContextoExecucaoOO1; import loo1.plp.orientadaObjetos1.memoria.DefClasse; import loo1.plp.orientadaObjetos1.memoria.Objeto; import loo1.plp.orientadaObjetos1.memoria.colecao.ListaValor; import loo1.plp.orientadaObjetos1.util.Tipo; /** * Classe que representa a chamada de um m�todo. */ public class ChamadaMetodo implements Comando { /** * A express�o que chama o m�todo. */ protected Expressao expressao; /** * O identificador que representa o nome do m�todo. */ protected Id nomeMetodo; /** * Par�metros passados para o m�todo. */ protected ListaExpressao parametrosReais; /** * Construtor. * @param expressao A expressao chamadora do m�todo. * @param nomeMetodo O nome do m�todo. * @param parametrosReais Os par�metros passados para a execu��o do m�todo. * @param */ public ChamadaMetodo(Expressao expressao, Id nomeMetodo, ListaExpressao parametrosReais){ this.expressao = expressao; this.nomeMetodo = nomeMetodo; this.parametrosReais = parametrosReais; } /** * Executa uma chamada de m�todo. * @param ambiente O ambiente de execu��o, que guarda o mapeamento * de identificadores a valores. * @return o Ambiente de Execu��o atualizado. */ public AmbienteExecucaoOO1 executar(AmbienteExecucaoOO1 ambiente) throws VariavelJaDeclaradaException, VariavelNaoDeclaradaException, ProcedimentoNaoDeclaradoException, ProcedimentoJaDeclaradoException, ObjetoJaDeclaradoException, ObjetoNaoDeclaradoException, ClasseNaoDeclaradaException, ClasseJaDeclaradaException, EntradaInvalidaException{ ValorRef vr = (ValorRef) expressao.avaliar(ambiente); // recupera o id do objeto Objeto objeto = ambiente.getObjeto(vr); // recupera o objeto Id idClasse = objeto.getClasse(); // recupera o tipo do objeto DefClasse defClasse = ambiente.getDefClasse((loo1.plp.expressions2.expression.Id)idClasse); // recupera a defini��o da classe Procedimento metodo = defClasse.getMetodo(nomeMetodo); // recupera o procedimento // cria um novo ambiente para a execucao, pois // n�o deve levar em conta as vari�veis definidas na main AmbienteExecucaoOO1 aux = new ContextoExecucaoOO1(ambiente); // � change pois no construtor do ambiente aux.changeValor(new Id("this"),vr); // invocado na linha anterior ja � feito // um mapeamento ListaValor valoresDosParametros = parametrosReais.avaliar(ambiente); new ChamadaProcedimento(metodo, parametrosReais, valoresDosParametros).executar(aux); return ambiente; } /** * Realiza a verifica��o de tipos desta chamada de m�todo, onde * o tipo do m�todo deve estar na defini��o da classe obtida * a partir de express�o. * * @param ambiente o ambiente que contem o mapeamento entre identificadores * e tipos. * @return true se a chamada de m�todo est� bem tipada; * false caso contrario. */ public boolean checaTipo(AmbienteCompilacaoOO1 ambiente) throws VariavelNaoDeclaradaException, VariavelJaDeclaradaException, ClasseNaoDeclaradaException { boolean resposta; //Antes de incrementar o ambiente, verifico se o m�todo //� v�lido para a definicao de classe obtida a partir de expressao. //Se n�o for v�lido, a exce��o ProcedimentoNaoDeclaradoException ser� //lan�ada e checaTipo retornar� false. Tipo tipoClasse = expressao.getTipo(ambiente); DefClasse defClasse = ambiente.getDefClasse(tipoClasse.getTipo()); try{ Procedimento metodo = defClasse.getMetodo(nomeMetodo); ambiente.incrementa(); ambiente.map(new Id("this"),tipoClasse); resposta = new ChamadaProcedimento(metodo, parametrosReais).checaTipo(ambiente); ambiente.restaura(); } catch(ProcedimentoNaoDeclaradoException e){ resposta = false; } return resposta; } }