All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gw.internal.gosu.parser.GosuFragmentParser Maven / Gradle / Ivy

There is a newer version: 1.18.2
Show newest version
/*
 * Copyright 2014 Guidewire Software, Inc.
 */

package gw.internal.gosu.parser;

import gw.internal.gosu.parser.fragments.GosuFragment;
import gw.lang.parser.GosuParserFactory;
import gw.lang.parser.IExpression;
import gw.lang.parser.IFileContext;
import gw.lang.parser.IFunctionSymbol;
import gw.lang.parser.IGosuFragmentParser;
import gw.lang.parser.IGosuParser;
import gw.lang.parser.ISymbol;
import gw.lang.parser.ISymbolTable;
import gw.lang.parser.ParserOptions;
import gw.lang.parser.ScriptPartId;
import gw.lang.parser.exceptions.ParseResultsException;
import gw.lang.reflect.FragmentCache;
import gw.lang.reflect.TypeSystem;
import gw.lang.reflect.gs.IGosuFragment;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public class GosuFragmentParser implements IGosuFragmentParser {

  private static final GosuFragmentParser _instance = new GosuFragmentParser();
  private static AtomicInteger _fragmentCount = new AtomicInteger();
  public static GosuFragmentParser getInstance() {
    return _instance;
  }

  private GosuFragmentParser() { }

  public IGosuFragment parseExpressionOnly( String script, ISymbolTable table, ParserOptions options) throws ParseResultsException {
    return parseImpl( script, table, options, determineName( options.getFileContext() ), determineExternalSymbols( table, options ), true );
  }

  public IGosuFragment parseProgramOnly( String script, ISymbolTable table, ParserOptions options) throws ParseResultsException {
    return parseImpl( script, table, options, determineName( options.getFileContext() ), determineExternalSymbols( table, options ), false );
  }

  public IGosuFragment parseExpressionOrProgram(String script, ISymbolTable table, ParserOptions options) throws ParseResultsException {
    String name = determineName(options.getFileContext());
    HashMap externalSymbolNames = determineExternalSymbols( table, options );
    try {
      return parseImpl( script, table, options, name, externalSymbolNames, true );
    } catch (ParseResultsException pe) {
      try {
        return parseImpl( script, table, options, name, externalSymbolNames, false );
      } catch (ParseResultsException peProg) {
        throw pe;
      }
    }
  }

  private IGosuFragment parseImpl( String script, ISymbolTable table, ParserOptions options, String name, HashMap externalSymbols, boolean parseExpression ) throws ParseResultsException {
    IGosuParser parser = GosuParserFactory.createParser( script );
    parser.putDfsDeclsInTable( table );
    options.setParserOptions( parser );

    GosuFragment fragment = new GosuFragment( name, externalSymbols, options.getTypeUsesMap() );
    FragmentCache.instance().addFragment(fragment);
    TypeSystem.pushSymTableCtx(table);
    try{
      parser.setSymbolTable( TypeSystem.getCompiledGosuClassSymbolTable() ); // Set up the symbol table
      // Create the fragment and put it in the map so that references during parsing can find it

      IExpression result;
      CompiledGosuClassSymbolTable.instance().pushCompileTimeSymbolTable( fragment, table );
      try {
        if (parseExpression) {
          result = parser.parseExp( new ScriptPartId(fragment, null), options.getExpectedType(), options.getFileContext(), false );
        } else {
          
          result = parser.parseProgram( new ScriptPartId(fragment, null), true, true, options.getExpectedType(), options.getFileContext(), false );
        }
      } finally {
        CompiledGosuClassSymbolTable.instance().popCompileTimeSymbolTable( fragment );
      }
      fragment.setExpression( result );     
      return fragment;
    } catch (ParseResultsException e) {
      if (e.hasOnlyParseWarnings()) {
        IExpression result = (IExpression) e.getParsedElement();
        fragment.setExpression(result);
        return fragment;
      } else {
        throw e;
      }
    } finally {
      TypeSystem.popSymTableCtx();
    }
  }

  private String determineName( IFileContext fileContext ) {
    String name = fileContext == null ? null : fileContext.getClassName();
    if( name == null )
    {
      name = GosuFragment.FRAGMENT_NAME_PREFIX + _fragmentCount.getAndIncrement();
    }
    if( fileContext != null && fileContext.getContextString() != null)
    {
      name += "_" + fileContext.getContextString();
    }
    return name;
  }

  private HashMap determineExternalSymbols( ISymbolTable symbolTable, ParserOptions options ) {
    Map symbols = symbolTable.getSymbols();
    if( symbols == null && options.getAdditionalDFSDecls() == null && options.getDeclSymbols() == null)
    {
      return new HashMap( 0 );
    }

    HashMap symbolNames = new HashMap( 8 );
    if (symbols != null) {
      //noinspection unchecked
      for (ISymbol sym : (Collection) symbols.values()) {
        if (!(sym instanceof CommonSymbolsScope.LockedDownSymbol) && sym != null) {
          symbolNames.put( sym.getName(), sym);
        }
      }
    }

    ISymbolTable decls = options.getAdditionalDFSDecls();
    if (decls != null) {
      //noinspection unchecked
      for (ISymbol sym : (Collection) decls.getSymbols().values()) {
        if (!(sym instanceof CommonSymbolsScope.LockedDownSymbol) && sym != null) {
          symbolNames.put( sym.getName(), sym);
        }
      }
    }

    Map> declSymbolMap = options.getDeclSymbols();
    if (declSymbolMap != null) {
      for (List symbolSet : declSymbolMap.values()) {
        for (IFunctionSymbol sym : symbolSet) {
          if (!(sym instanceof CommonSymbolsScope.LockedDownSymbol) && sym != null) {
            symbolNames.put( sym.getName(), sym);
          }
        }
      }
    }

    return symbolNames;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy