/******************************************************************************* * Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package org.eclipse.xtext.xbase.serializer; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.Keyword; import org.eclipse.xtext.RuleCall; import org.eclipse.xtext.nodemodel.ICompositeNode; import org.eclipse.xtext.nodemodel.ILeafNode; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.serializer.analysis.ISyntacticSequencerPDAProvider.ISynNavigable; import org.eclipse.xtext.xbase.XBinaryOperation; import org.eclipse.xtext.xbase.XBlockExpression; import org.eclipse.xtext.xbase.XConstructorCall; import org.eclipse.xtext.xbase.XExpression; import org.eclipse.xtext.xbase.XForLoopExpression; import org.eclipse.xtext.xbase.XIfExpression; import org.eclipse.xtext.xbase.XPostfixOperation; import org.eclipse.xtext.xbase.XTryCatchFinallyExpression; import org.eclipse.xtext.xbase.XUnaryOperation; public class XbaseSyntacticSequencer extends AbstractXbaseSyntacticSequencer { boolean semicolonBeforeNextExpressionRequired = false; /** * Syntax: '('* */ @Override protected void emit_XParenthesizedExpression_LeftParenthesisKeyword_0_a(EObject semanticObject, ISynNavigable transition, List<INode> nodes) { Keyword kw = grammarAccess.getXParenthesizedExpressionAccess().getLeftParenthesisKeyword_0(); if (nodes == null) { if (semanticObject instanceof XIfExpression || semanticObject instanceof XTryCatchFinallyExpression) { EObject cnt = semanticObject.eContainer(); if (cnt instanceof XExpression && !(cnt instanceof XBlockExpression) && !(cnt instanceof XForLoopExpression)) acceptUnassignedKeyword(kw, kw.getValue(), null); } if (semanticObject instanceof XConstructorCall) { XConstructorCall call = (XConstructorCall) semanticObject; if (!call.isExplicitConstructorCall() && call.getArguments().isEmpty()) { acceptUnassignedKeyword(kw, kw.getValue(), null); } } } acceptNodes(transition, nodes); } protected boolean startsWithUnaryOperator(EObject obj) { if(obj instanceof XUnaryOperation) return true; if(obj instanceof XBinaryOperation) return startsWithUnaryOperator(((XBinaryOperation)obj).getLeftOperand()); if(obj instanceof XPostfixOperation) { return startsWithUnaryOperator(((XPostfixOperation)obj).getOperand()); } return false; } @Override public boolean enterAssignedParserRuleCall(RuleCall rc, EObject semanticChild, ICompositeNode node) { if (rc == grammarAccess.getXBlockExpressionAccess().getExpressionsXExpressionOrVarDeclarationParserRuleCall_2_0_0()) { semicolonBeforeNextExpressionRequired = startsWithUnaryOperator(semanticChild); } else semicolonBeforeNextExpressionRequired = false; return super.enterAssignedParserRuleCall(rc, semanticChild, node); } /** * Syntax: * ';'? */ @Override protected void emit_XBlockExpression_SemicolonKeyword_2_1_q(EObject semanticObject, ISynNavigable transition, List<INode> nodes) { if (semicolonBeforeNextExpressionRequired) { ILeafNode node = nodes != null && nodes.size() == 1 && nodes.get(0) instanceof ILeafNode ? (ILeafNode) nodes.get(0) : null; Keyword kw = grammarAccess.getXBlockExpressionAccess().getSemicolonKeyword_2_1(); acceptUnassignedKeyword(kw, kw.getValue(), node); } else acceptNodes(transition, nodes); } @Override protected String getArrayBracketsToken(EObject semanticObject, RuleCall ruleCall, INode node) { if (node != null) return getTokenText(node); return "[]"; } }