/* * $Id$ * * File is automatically generated by the Xtext language generator. * Do not change it. * * SARL is an general-purpose agent programming language. * More details on http://www.sarl.io * * Copyright (C) 2014-2017 the original authors or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.sarl.lang.serializer; import io.sarl.lang.documentation.IEcoreDocumentationBuilder; import io.sarl.lang.documentation.InnerBlockDocumentationAdapter; import io.sarl.lang.services.SARLGrammarKeywordAccess; import java.lang.reflect.Field; import java.util.HashSet; import java.util.Set; import javax.inject.Inject; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.xtext.AbstractRule; import org.eclipse.xtext.Keyword; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.serializer.ISerializationContext; import org.eclipse.xtext.serializer.acceptor.ISequenceAcceptor; import org.eclipse.xtext.serializer.acceptor.ISyntacticSequenceAcceptor; import org.eclipse.xtext.serializer.analysis.ISyntacticSequencerPDAProvider.ISynState; import org.eclipse.xtext.serializer.analysis.ISyntacticSequencerPDAProvider.ISynTransition; import org.eclipse.xtext.serializer.analysis.ISyntacticSequencerPDAProvider.SynStateType; import org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic; import org.eclipse.xtext.serializer.sequencer.HiddenTokenSequencer; import org.eclipse.xtext.serializer.sequencer.RuleCallStack; import org.eclipse.xtext.util.Strings; import org.eclipse.xtext.xbase.XBlockExpression; import org.eclipse.xtext.xbase.compiler.DocumentationAdapter; /** Syntactic sequencer which supports documentations of Ecore elements. */ public class SARLEcoreDocumentationSyntacticSequencer extends SARLSyntacticSequencer { private final Set<EObject> documentedSemanticObjects = new HashSet<>(); private final Set<EObject> indocumentedSemanticObjects = new HashSet<>(); private InnerBlockDocumentationAdapter lastInnerBlock; @Inject private IEcoreDocumentationBuilder documentationBuilder; @Inject private SARLGrammarKeywordAccess keywords; private ISequenceAcceptor trailingSequenceAcceptor; public void init(ISerializationContext context, EObject semanticObject, ISyntacticSequenceAcceptor sequenceAcceptor, ISerializationDiagnostic.Acceptor errorAcceptor) { super.init(context, semanticObject, sequenceAcceptor, errorAcceptor); if (sequenceAcceptor instanceof ISequenceAcceptor) { this.trailingSequenceAcceptor = (ISequenceAcceptor) sequenceAcceptor; } this.documentedSemanticObjects.clear(); this.indocumentedSemanticObjects.clear(); this.lastInnerBlock = null; } protected ISequenceAcceptor getTrailingSequenceAcceptor() { if (this.trailingSequenceAcceptor == null) { try { Field delegateField = HiddenTokenSequencer.class.getDeclaredField("delegate"); delegateField.setAccessible(true); this.trailingSequenceAcceptor = (ISequenceAcceptor) delegateField.get(this.delegate); } catch (Throwable exception) { throw new RuntimeException(exception); } } return this.trailingSequenceAcceptor; } protected void emitDocumentation(Class<?> semanticObjectType, String comment) { final String fmtcomment = this.documentationBuilder.build(comment, semanticObjectType); if (!Strings.isEmpty(fmtcomment)) { final AbstractRule rule = this.documentationBuilder.isMultilineCommentFor(semanticObjectType) ? this.documentationBuilder.getMLCommentRule() : this.documentationBuilder.getSLCommentRule(); getTrailingSequenceAcceptor().acceptComment(rule, fmtcomment, null); } } protected void emitDocumentation(EObject semanticObject) { if (this.documentedSemanticObjects.add(semanticObject)) { DocumentationAdapter documentationAdapter = (DocumentationAdapter) EcoreUtil.getAdapter(semanticObject.eAdapters(), DocumentationAdapter.class); if (documentationAdapter != null) { emitDocumentation(semanticObject.getClass(), documentationAdapter.getDocumentation()); } } } protected void emitInnerDocumentation(EObject semanticObject) { if (this.indocumentedSemanticObjects.add(semanticObject)) { InnerBlockDocumentationAdapter documentationAdapter = (InnerBlockDocumentationAdapter) EcoreUtil.getAdapter(semanticObject.eAdapters(), InnerBlockDocumentationAdapter.class); if (documentationAdapter != null) { emitDocumentation(semanticObject.getClass(), documentationAdapter.getDocumentation()); } } } private InnerBlockDocumentationAdapter getInnerDocumentation(EObject semanticObject) { if (this.indocumentedSemanticObjects.add(semanticObject)) { return (InnerBlockDocumentationAdapter) EcoreUtil.getAdapter(semanticObject.eAdapters(), InnerBlockDocumentationAdapter.class); } return null; } protected void emitUnassignedTokens(EObject semanticObject, ISynTransition transition, INode fromNode, INode toNode) { super.emitUnassignedTokens(semanticObject, transition, fromNode, toNode); emitDocumentation(semanticObject); if (semanticObject instanceof XBlockExpression) { this.lastInnerBlock = getInnerDocumentation(semanticObject); } } protected void accept(ISynState emitter, INode node, RuleCallStack stack) { super.accept(emitter, node, stack); final InnerBlockDocumentationAdapter documentation = this.lastInnerBlock; if (documentation != null && emitter.getType() == SynStateType.UNASSIGEND_KEYWORD) { Keyword keyword = (Keyword) emitter.getGrammarElement(); String token = node != null ? node.getText() : keyword.getValue(); if (Strings.equal(token, this.keywords.getLeftCurlyBracketKeyword())) { this.lastInnerBlock = null; emitDocumentation(documentation.getTarget().getClass(), documentation.getDocumentation()); } } } }