NamespaceSymbol.java :  » UnTagged » simplecompiler2 » com » google » devtools » simple » compiler » symbols » Android Open Source

Android Open Source » UnTagged » simplecompiler2 
simplecompiler2 » com » google » devtools » simple » compiler » symbols » NamespaceSymbol.java
/*
 * Copyright 2009 Google Inc.
 *
 * 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 com.google.devtools.simple.compiler.symbols;

import com.google.devtools.simple.classfiles.Method;
import com.google.devtools.simple.compiler.Compiler;
import com.google.devtools.simple.compiler.scanner.Scanner;
import com.google.devtools.simple.compiler.scopes.GlobalScope;
import com.google.devtools.simple.compiler.scopes.NamespaceScope;
import com.google.devtools.simple.compiler.scopes.Scope;
import com.google.devtools.simple.util.Files;
import com.google.devtools.simple.util.Preconditions;

import java.io.File;

/**
 * Symbol used for defining namespaces.
 * 
 * @author Herbert Czymontek
 */
public final class NamespaceSymbol extends Symbol implements SymbolCanBePartOfQualifiedIdentifier {

  // Enclosing namespace
  private NamespaceSymbol outerNamespace;

  // Namespace scope
  private Scope scope;

  /**
   * Factory method for namespace symbols.
   * 
   * @param compiler  current compiler instance
   * @param packageName  package name of namespace in internal format
   * @return  namespace symbol
   */
  public static NamespaceSymbol getNamespaceSymbol(Compiler compiler, String packageName) {
    // Search for an existing namespace symbol always starts with the global/root namespace
    NamespaceSymbol outerNamespace = compiler.getGlobalNamespaceSymbol();

    for (;;) {
      // Scope to look in for next package
      Scope scope = outerNamespace.getScope();
      int index = packageName.indexOf('.');
      if (index == -1) {
        // Last package component
        NamespaceSymbol namespace = (NamespaceSymbol)scope.lookupShallow(packageName);
        return namespace == null ? new NamespaceSymbol(packageName, outerNamespace) : namespace;
      } else {
        // Package prefix
        String name = packageName.substring(0, index);
        packageName = packageName.substring(index + 1);
        NamespaceSymbol namespace = (NamespaceSymbol)scope.lookupShallow(name);
        outerNamespace = namespace == null ? new NamespaceSymbol(name, outerNamespace) : namespace;
      }
    }
  }

  /*
   * Creates a new nested namespace symbol.
   */
  private NamespaceSymbol(String name, NamespaceSymbol outerNamespace) {
    super(Scanner.NO_POSITION, name);
    Preconditions.checkArgument(outerNamespace != null);

    this.outerNamespace = outerNamespace;

    Scope outerScope = outerNamespace.getScope();
    scope = new NamespaceScope(outerScope);
    outerScope.enterSymbol(this);
  }

  /**
   * Creates a new root namespace symbol for the global scope.
   * 
   * <p>Note that this constructor may only be called once for any compiler
   * instance, preferably in its constructor.
   */
  public NamespaceSymbol() {
    super(Scanner.NO_POSITION, null);
    scope = new GlobalScope();
  }

  public Scope getScope() {
    return scope;
  }

  @Override
  public void generateRead(Method m) {
  }

  @Override
  public void generateWrite(Method m) {
  }

  /**
   * Generates the directory structure for the namespace on the filesystem.
   * 
   * @param rootDir  root directory for namespace structure
   * @return  file descriptor for namespace
   */
  public File generate(File rootDir) {
    if (outerNamespace == null) {
      return rootDir;
    }

    return Files.createDirectory(outerNamespace.generate(rootDir), getName());
  }

  /**
   * Returns the internal name of the namespace.
   * 
   * @return  internal namespace name
   */
  public String internalName() {
    return (outerNamespace == null) ? "" : (outerNamespace.internalName() + getName() + '/');
  }

  /*
   * Returns the outer namespaces for toString().
   */
  private String prependOuterNamespaceName() {
    return (outerNamespace == null) ? "" :
        (outerNamespace.prependOuterNamespaceName() + getName() + ':');
  }
  
  @Override
  public String toString() {
    return "<namespace> " + prependOuterNamespaceName();
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.