View Javadoc
1   /*
2    * Themis: Java Project Framework
3    * Copyright 2012-2026. Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6    * use this file except in compliance with the License.  You may obtain a copy
7    * of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
14   * License for the specific language governing permissions and limitations under
15   * the License.
16   */
17  package io.github.tonywasher.joceanus.themis.lethe.analysis;
18  
19  import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20  import io.github.tonywasher.joceanus.themis.lethe.analysis.ThemisAnalysisIf.ThemisIteratorChain;
21  import io.github.tonywasher.joceanus.themis.lethe.analysis.ThemisAnalysisStatement.ThemisAnalysisStatementHolder;
22  
23  import java.util.Collections;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.ListIterator;
27  
28  /**
29   * Field Representation.
30   */
31  public class ThemisAnalysisField
32          implements ThemisAnalysisProcessed, ThemisAnalysisStatementHolder {
33      /**
34       * The name of the class.
35       */
36      private final String theName;
37  
38      /**
39       * The dataType of the field.
40       */
41      private final ThemisAnalysisReference theDataType;
42  
43      /**
44       * The properties.
45       */
46      private final ThemisAnalysisProperties theProperties;
47  
48      /**
49       * The initial value.
50       */
51      private final ThemisAnalysisStatement theInitial;
52  
53      /**
54       * The number of lines.
55       */
56      private final int theNumLines;
57  
58      /**
59       * Constructor.
60       *
61       * @param pParser   the parser
62       * @param pName     the method name
63       * @param pDataType the dataType
64       * @param pLine     the initial field line
65       * @throws OceanusException on error
66       */
67      ThemisAnalysisField(final ThemisAnalysisParser pParser,
68                          final String pName,
69                          final ThemisAnalysisReference pDataType,
70                          final ThemisAnalysisLine pLine) throws OceanusException {
71          /* Store parameters */
72          theName = pName;
73          theDataType = pDataType;
74          theProperties = pLine.getProperties();
75  
76          /* If we have no initial value */
77          if (pLine.startsWithChar(ThemisAnalysisChar.SEMICOLON)) {
78              /* Set default values */
79              theNumLines = 1;
80              theInitial = null;
81  
82              /* else we have an initializer */
83          } else {
84              /* Strip the equals sign */
85              pLine.stripStartChar(ThemisAnalysisChar.EQUAL);
86  
87              /* Declare as statement */
88              theInitial = new ThemisAnalysisStatement(pParser, pLine);
89              theNumLines = theInitial.getNumLines();
90          }
91      }
92  
93      /**
94       * Constructor.
95       *
96       * @param pParser   the parser
97       * @param pName     the method name
98       * @param pDataType the dataType
99       * @param pEmbedded the embedded block
100      * @throws OceanusException on error
101      */
102     ThemisAnalysisField(final ThemisAnalysisParser pParser,
103                         final String pName,
104                         final ThemisAnalysisReference pDataType,
105                         final ThemisAnalysisEmbedded pEmbedded) throws OceanusException {
106         /* Store parameters */
107         theName = pName;
108         theDataType = pDataType;
109 
110         /* Access header line */
111         final ThemisAnalysisLine myLine = pEmbedded.getHeader();
112         theProperties = myLine.getProperties();
113 
114         /* Strip the equals sign */
115         myLine.stripStartChar(ThemisAnalysisChar.EQUAL);
116 
117         /* Declare as statement */
118         theInitial = new ThemisAnalysisStatement(pEmbedded);
119         theNumLines = theInitial.getNumLines();
120     }
121 
122     /**
123      * Constructor.
124      *
125      * @param pDataMap the dataMap
126      * @param pStack   the field stack
127      * @throws OceanusException on error
128      */
129     ThemisAnalysisField(final ThemisAnalysisDataMap pDataMap,
130                         final ThemisAnalysisStack pStack) throws OceanusException {
131         /* Determine initial parameters */
132         final ThemisAnalysisLine myLine = (ThemisAnalysisLine) pStack.popNextLine();
133         ThemisAnalysisProperties myProps = ThemisAnalysisProperties.NULL;
134 
135         /* Access the next token */
136         final String nextToken = myLine.peekNextToken();
137 
138         /* If this is a final modifier */
139         if (ThemisAnalysisModifier.FINAL.getModifier().equals(nextToken)) {
140             /* Record modifier and strip it */
141             myProps = myProps.setModifier(ThemisAnalysisModifier.FINAL);
142             myLine.stripStartSequence(nextToken);
143         }
144 
145         /* Process remaining data */
146         theDataType = ThemisAnalysisParser.parseDataType(pDataMap, myLine);
147         theName = myLine.stripNextToken();
148         myLine.stripStartChar(ThemisAnalysisChar.EQUAL);
149         pStack.pushLine(myLine);
150         theProperties = myProps;
151 
152         /* Declare as statement */
153         theInitial = new ThemisAnalysisStatement(null, pStack);
154         theNumLines = theInitial.getNumLines();
155     }
156 
157     /**
158      * Constructor.
159      *
160      * @param pPrevious the previous field
161      * @param pStack    the field stack
162      * @throws OceanusException on error
163      */
164     ThemisAnalysisField(final ThemisAnalysisField pPrevious,
165                         final ThemisAnalysisStack pStack) throws OceanusException {
166         /* Determine initial parameters */
167         final ThemisAnalysisLine myLine = (ThemisAnalysisLine) pStack.popNextLine();
168         theDataType = pPrevious.theDataType;
169         theName = myLine.stripNextToken();
170         myLine.stripStartChar(ThemisAnalysisChar.EQUAL);
171         pStack.pushLine(myLine);
172         theProperties = ThemisAnalysisProperties.NULL;
173 
174         /* Declare as statement */
175         theInitial = new ThemisAnalysisStatement(null, pStack);
176         theNumLines = theInitial.getNumLines();
177     }
178 
179     /**
180      * Obtain the name.
181      *
182      * @return the name
183      */
184     public String getName() {
185         return theName;
186     }
187 
188     @Override
189     public Iterator<ThemisAnalysisStatement> statementIterator() {
190         return theInitial == null
191                 ? Collections.emptyIterator()
192                 : Collections.singleton(theInitial).iterator();
193     }
194 
195     @Override
196     public int getNumLines() {
197         return theNumLines;
198     }
199 
200     @Override
201     public String toString() {
202         return theDataType.toString() + " " + getName();
203     }
204 
205     /**
206      * Obtain statement iterator for list of fields.
207      *
208      * @param pList the field list
209      * @return the statement iterator
210      */
211     public static Iterator<ThemisAnalysisStatement> statementIteratorForFields(final List<ThemisAnalysisField> pList) {
212         final ListIterator<ThemisAnalysisField> myIterator = pList.listIterator(pList.size());
213         Iterator<ThemisAnalysisStatement> myCurr = Collections.emptyIterator();
214         while (myIterator.hasPrevious()) {
215             final ThemisAnalysisField myField = myIterator.previous();
216             myCurr = new ThemisIteratorChain<>(myField.statementIterator(), myCurr);
217         }
218         return myCurr;
219     }
220 }