| /*=============================================================================# |
| # Copyright (c) 2009, 2021 Stephan Wahlbrink 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 |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.internal.r.core.sourcemodel; |
| |
| import java.util.HashMap; |
| |
| import org.eclipse.statet.internal.r.core.sourcemodel.RSourceElementByElementAccess.RClass; |
| import org.eclipse.statet.internal.r.core.sourcemodel.RSourceElementByElementAccess.RMethod; |
| import org.eclipse.statet.r.core.model.RElement; |
| import org.eclipse.statet.r.core.model.RLangSourceElement; |
| import org.eclipse.statet.r.core.model.RSourceFrame; |
| import org.eclipse.statet.r.core.rsource.ast.DocuTag; |
| import org.eclipse.statet.r.core.rsource.ast.NodeType; |
| import org.eclipse.statet.r.core.rsource.ast.RAstNode; |
| |
| |
| /** |
| * Describes how to handle special Roxygen tags |
| */ |
| public abstract class RoxygenTagType { |
| |
| |
| public static final int INITIAL= 0x0; |
| |
| public static final int SCAN_MODE_FREETEXT= 0x0; |
| public static final int SCAN_MODE_SYMBOL= 0x1; |
| public static final int SCAN_MODE_RCODE= 0x2; |
| |
| public static final int FRAGMENT_ACTION_SELF_ACCESS= 0x1; |
| public static final int FRAGMENT_ACTION_PARAM_ACCESS= 0x2; |
| public static final int FRAGMENT_ACTION_SLOT_ACCESS= 0x3; |
| public static final int FRAGMENT_ACTION_PACKAGE_IMPORT= 0x4; |
| |
| |
| public static final HashMap<String, RoxygenTagType> TYPES= new HashMap<>(); |
| |
| static { |
| TYPES.put("param", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| if (previous == INITIAL) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| return 0x900; |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| if (element == null || (element.getElementType() & RElement.MASK_C1) != RElement.C1_METHOD) { |
| return; |
| } |
| final int count= docuTag.getChildCount(); |
| if (count >= 1) { |
| final RAstNode child= docuTag.getChild(0); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createArgAccess(docuTag, (RMethod)element, child); |
| } |
| } |
| } |
| }); |
| TYPES.put("slot", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| if (previous == INITIAL) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| return 0x900; |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| if (element == null || (element.getElementType() & RElement.MASK_C1) != RElement.C1_CLASS) { |
| return; |
| } |
| final int count= docuTag.getChildCount(); |
| if (count >= 1) { |
| final RAstNode child= docuTag.getChild(0); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createSlotAccess(docuTag, (RClass)element, child); |
| } |
| } |
| } |
| }); |
| TYPES.put("name", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| if (previous == INITIAL) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| return 0x900; |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| if (element == null) { |
| return; |
| } |
| final int count= docuTag.getChildCount(); |
| if (count >= 1) { |
| final RAstNode child= docuTag.getChild(0); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createSelfAccess(docuTag, element, child); |
| } |
| } |
| } |
| }); |
| TYPES.put("aliases", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| if (element == null) { |
| return; |
| } |
| final int count= docuTag.getChildCount(); |
| for (int i= 0; i < count; i++) { |
| final RAstNode child= docuTag.getChild(i); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createSelfAccess(docuTag, element, child); |
| } |
| } |
| } |
| }); |
| TYPES.put("export", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| if (element == null) { |
| return; |
| } |
| final int count= docuTag.getChildCount(); |
| for (int i= 0; i < count; i++) { |
| final RAstNode child= docuTag.getChild(i); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createSelfAccess(docuTag, element, child); |
| } |
| } |
| } |
| }); |
| TYPES.put("exportClass", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| if (element == null |
| || ((element.getElementType() & RElement.MASK_C1) != RElement.C1_CLASS |
| && (element.getElementType() & RElement.MASK_C1) != RElement.C1_VARIABLE) ) { |
| return; |
| } |
| final int count= docuTag.getChildCount(); |
| for (int i= 0; i < count; i++) { |
| final RAstNode child= docuTag.getChild(i); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createSelfAccess(docuTag, element, child); |
| } |
| } |
| } |
| }); |
| TYPES.put("exportMethod", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| if (element == null |
| || ((element.getElementType() & RElement.MASK_C1) != RElement.C1_METHOD |
| && (element.getElementType() & RElement.MASK_C1) != RElement.C1_VARIABLE) ) { |
| return; |
| } |
| final int count= docuTag.getChildCount(); |
| for (int i= 0; i < count; i++) { |
| final RAstNode child= docuTag.getChild(i); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createSelfAccess(docuTag, element, child); |
| } |
| } |
| } |
| }); |
| TYPES.put("import", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| final int count= docuTag.getChildCount(); |
| for (int i= 0; i < count; i++) { |
| final RAstNode child= docuTag.getChild(i); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createNamespaceImportAccess(docuTag, child); |
| } |
| } |
| } |
| }); |
| TYPES.put("importFrom", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| final int count= docuTag.getChildCount(); |
| if (count >= 1) { |
| RAstNode child= docuTag.getChild(0); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createNamespaceImportAccess(docuTag, child); |
| } |
| final String name= child.getText(); |
| |
| if (count >= 2 && name != null) { |
| final RSourceFrame frame= context.getNamespaceFrame(name); |
| if (frame != null) { |
| for (int i= 1; i < count; i++) { |
| child= docuTag.getChild(i); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createNamespaceObjectImportAccess(docuTag, frame, child); |
| } |
| } |
| } |
| } |
| } |
| } |
| }); |
| TYPES.put("importClassesFrom", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| final int count= docuTag.getChildCount(); |
| if (count >= 1) { |
| final RAstNode child= docuTag.getChild(0); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createNamespaceImportAccess(docuTag, child); |
| } |
| } |
| } |
| }); |
| TYPES.put("importMethodsFrom", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| return (0x100 | SCAN_MODE_SYMBOL); |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| final int count= docuTag.getChildCount(); |
| if (count >= 1) { |
| final RAstNode child= docuTag.getChild(0); |
| if (child.getNodeType() == NodeType.SYMBOL) { |
| context.createNamespaceImportAccess(docuTag, child); |
| } |
| } |
| } |
| }); |
| TYPES.put("examples", new RoxygenTagType() { |
| @Override |
| public int getNextScanMode(final int previous) { |
| return (0x100 | SCAN_MODE_RCODE); |
| } |
| @Override |
| public void analyze(final RoxygenAnalyzeContext context, final DocuTag docuTag, final RLangSourceElement element) { |
| final int count= docuTag.getChildCount(); |
| if (count >= 1) { |
| final RAstNode child= docuTag.getChild(0); |
| if (child.getNodeType() == NodeType.SOURCELINES) { |
| context.createRSourceRegion(child); |
| } |
| } |
| } |
| }); |
| } |
| |
| |
| public RoxygenTagType() { |
| } |
| |
| |
| public abstract int getNextScanMode(int previous); |
| |
| public abstract void analyze(RoxygenAnalyzeContext context, DocuTag docuTag, RLangSourceElement element); |
| |
| |
| } |