/*******************************************************************************
* Copyright (c) 2009 xored software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.itcl.internal.core.parser.structure;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.dltk.itcl.internal.core.parser.structure.model.IClass;
import org.eclipse.dltk.tcl.core.TclParseUtil;
import org.eclipse.dltk.tcl.structure.ITclModelBuildContext;
public class IncrTclNames {
private static final String ATTR = IncrTclNames.class.getName();
public static IncrTclNames get(ITclModelBuildContext context) {
return (IncrTclNames) context.getAttribute(ATTR);
}
public static IncrTclNames create(ITclModelBuildContext context) {
IncrTclNames names = get(context);
if (names == null) {
names = new IncrTclNames();
context.setAttribute(ATTR, names);
}
return names;
}
static class IncrTclTypeInfo {
final String[] segments;
final IClass clazz;
public IncrTclTypeInfo(String[] segments, IClass clazz) {
this.segments = segments;
this.clazz = clazz;
}
/**
* @param parts
* @return
*/
public boolean endsWith(String[] parts) {
final int pLen = parts.length;
final int sLen = segments.length;
if (pLen <= sLen) {
final int offset = sLen - pLen;
for (int i = 0; i < pLen; ++i) {
if (!parts[i].equals(segments[offset + i])) {
return false;
}
}
return true;
}
return false;
}
/**
* @return
*/
public String getSimpleName() {
return segments[segments.length - 1];
}
}
private final Map<String, Map<String, IncrTclTypeInfo>> names = new HashMap<String, Map<String, IncrTclTypeInfo>>();
/**
* @param typeInfo
* @param resolvedType
*/
public void addType(IClass clazz) {
String namespace = clazz.getName();
if (namespace.startsWith("::")) { //$NON-NLS-1$
namespace = namespace.substring(2);
}
if (namespace.length() == 0) {
return;
}
final String[] segments = TclParseUtil.tclSplit(namespace);
if (segments.length == 0) {
return;
}
final String lastName = segments[segments.length - 1];
Map<String, IncrTclTypeInfo> types = names.get(lastName);
if (types == null) {
types = new HashMap<String, IncrTclTypeInfo>();
names.put(lastName, types);
}
if (!types.containsKey(namespace)) {
types.put(namespace, new IncrTclTypeInfo(segments, clazz));
}
}
/**
* @param name
* @param nameArgument
* @return
*/
public IClass resolve(String name) {
String[] segments = TclParseUtil.tclSplit(name);
if (segments.length == 0) {
return null;
}
final Map<String, IncrTclTypeInfo> types = names
.get(segments[segments.length - 1]);
if (types == null) {
return null;
}
for (Map.Entry<String, IncrTclTypeInfo> entry : types.entrySet()) {
if (entry.getValue().endsWith(segments)) {
return entry.getValue().clazz;
}
}
return null;
}
private static final String TYPE_ATTR = ATTR + ".TYPE"; //$NON-NLS-1$
/**
* @param context
* @param type
*/
public static void saveType(ITclModelBuildContext context, IClass clazz) {
context.setAttribute(TYPE_ATTR, clazz);
}
public static IClass getType(ITclModelBuildContext context) {
return (IClass) context.getAttribute(TYPE_ATTR);
}
}