/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.util.transform.java.Visitor; import java.util.*; public class SymbolTable { private LinkedList<Scope> globals; private LinkedList<Scope> locals; private HashSet<String> reservedWords; int counter; private String[] reserved = {"true", "false", "NaN", "Infinity", "and", "or", "not", "null", "length", "exists", "in", "startswith", "contains", "where", "find", "var", "delegate", "represents", "as", "typeof", "statictypeof", "typeis", "typeas", "package", "uses", "if", "else", "except", "unless", "foreach", "for", "index", "iterator", "while", "do", "continue", "break", "return", "construct", "function", "property", "get", "set", "try", "catch", "finally", "this", "throw", "new", "switch", "case", "default", "eval", "private", "internal", "protected", "public", "abstract", "override", "hide", "final", "static", "extends", "transient", "implements", "readonly", "class", "interface", "structure", "enum", "super", "outer", "execution", "request", "session", "application", "void", "block", "enhancement", "classpath", "typeloader", "using", "now"}; private class Scope { String clazz; Set<String> idents; Map<String, String> conversions; Scope() { idents = new HashSet<String>(); conversions = new HashMap<String, String>(); } Scope(String clazz) { this.clazz = clazz; idents = new HashSet<String>(); conversions = new HashMap<String, String>(); } } public SymbolTable() { counter = 0; globals = new LinkedList<Scope>(); locals = new LinkedList<Scope>(); reservedWords = new HashSet<String>(); for(String word : reserved) { reservedWords.add(word); } } void pushGlobalScope(String clazz) { globals.add(new Scope(clazz)); } void pushLocalScope() { locals.add(new Scope()); } public String convertLocalSymbol(String ident) { Scope s; int end = locals.size() - 1; String converted = null; while (end >= 0) { s = locals.get(end); converted = s.conversions.get(ident); if (converted != null) { break; } end--; } return converted == null ? ident : converted; } String addLocally(String ident) { String original = ident; int i = 0; while (isDefinedLocally(ident) || isDefinedGlobally(ident) || isReserved(ident)) { ident = original + "_" + i; i++; } Scope last; try { last = locals.getLast(); } catch (NoSuchElementException ex) { throw new RuntimeException("Error: adding a new identifier in an empty scope." + "Have you forgotten to pushNewScope() first?"); } last.idents.add(ident); if (!original.equals(ident)) { last.conversions.put(original, ident); } return ident; } private boolean isReserved(String ident) { return reservedWords.contains(ident); } void popLocalScope() { try { locals.removeLast(); } catch (NoSuchElementException ex) { throw new RuntimeException("Error: the scope's stack is empty." + "Have you forgotten to pushNewScope() first?"); } } void popGlobalScope() { try { globals.removeLast(); } catch (NoSuchElementException ex) { throw new RuntimeException("Error: the scope's stack is empty." + "Have you forgotten to pushNewScope() first?"); } } private boolean isDefinedLocally(String ident) { int end = locals.size() - 1; while (end >= 0) { Scope s = locals.get(end); if (s.idents.contains(ident)) { return true; } end--; } return false; } private boolean isDefinedGlobally(String ident) { int end = globals.size() - 1; while (end >= 0) { Scope s = globals.get(end); if (s.idents.contains(ident)) { return true; } end--; } return false; } public int getClassLevelFromCurrent(String clazz) { int end = globals.size() - 1; int level = end; while (end >= 0) { Scope s = globals.get(end); if (s.clazz.equals(clazz)) { level -= end; break; } end--; } return level; } public String addGlobally(String ident) { Scope last; try { last = globals.getLast(); } catch (NoSuchElementException ex) { throw new RuntimeException("Error: adding a new identifier in an empty scope." + "Have you forgotten to pushNewScope() first?"); } last.idents.add(ident); return ident; } }